| Index: chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list_selection_model.js
|
| diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list_selection_model.js b/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list_selection_model.js
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8c16d577f5f2f9d5105df1511ebdbad9fabec353
|
| --- /dev/null
|
| +++ b/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list_selection_model.js
|
| @@ -0,0 +1,275 @@
|
| +// Copyright (c) 2011 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 Event = cr.Event;
|
| + const 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_ = [];
|
| + }
|
| +
|
| + ListSelectionModel.prototype = {
|
| + __proto__: EventTarget.prototype,
|
| +
|
| + /**
|
| + * The number of items in the model.
|
| + * @type {number}
|
| + */
|
| + get length() {
|
| + return this.length_;
|
| + },
|
| +
|
| + /**
|
| + * @type {!Array} The selected indexes.
|
| + */
|
| + get selectedIndexes() {
|
| + return Object.keys(this.selectedIndexes_).map(Number);
|
| + },
|
| + set selectedIndexes(selectedIndexes) {
|
| + this.beginChange();
|
| + this.unselectAll();
|
| + for (var i = 0; i < selectedIndexes.length; i++) {
|
| + this.setIndexSelected(selectedIndexes[i], true);
|
| + }
|
| + 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.
|
| + * @type {number}
|
| + */
|
| + get selectedIndex() {
|
| + for (var i in this.selectedIndexes_) {
|
| + return Number(i);
|
| + }
|
| + return -1;
|
| + },
|
| + set selectedIndex(selectedIndex) {
|
| + this.beginChange();
|
| + this.unselectAll();
|
| + if (selectedIndex != -1) {
|
| + this.selectedIndexes = [selectedIndex];
|
| + } else {
|
| + this.leadIndex = this.anchorIndex = -1;
|
| + }
|
| + this.endChange();
|
| + },
|
| +
|
| + /**
|
| + * 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();
|
| +
|
| + // Changing back?
|
| + if (index in this.changedIndexes_ && this.changedIndexes_[index] == !b) {
|
| + delete this.changedIndexes_[index];
|
| + } else {
|
| + 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.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_) {
|
| + var indexes = Object.keys(this.changedIndexes_);
|
| + if (indexes.length) {
|
| + var e = new Event('change');
|
| + e.changes = indexes.map(function(index) {
|
| + return {
|
| + index: index,
|
| + selected: this.changedIndexes_[index]
|
| + };
|
| + }, this);
|
| + this.dispatchEvent(e);
|
| + }
|
| + this.changedIndexes_ = {};
|
| + }
|
| + },
|
| +
|
| + leadIndex_: -1,
|
| +
|
| + /**
|
| + * 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 li = Math.max(-1, Math.min(this.length_ - 1, leadIndex));
|
| + if (li != this.leadIndex_) {
|
| + var oldLeadIndex = this.leadIndex_;
|
| + this.leadIndex_ = li;
|
| + cr.dispatchPropertyChange(this, 'leadIndex', li, oldLeadIndex);
|
| + }
|
| + },
|
| +
|
| + anchorIndex_: -1,
|
| +
|
| + /**
|
| + * The anchorIndex is used with multiple selection.
|
| + * @type {number}
|
| + */
|
| + get anchorIndex() {
|
| + return this.anchorIndex_;
|
| + },
|
| + set anchorIndex(anchorIndex) {
|
| + var ai = Math.max(-1, Math.min(this.length_ - 1, anchorIndex));
|
| + if (ai != this.anchorIndex_) {
|
| + var oldAnchorIndex = this.anchorIndex_;
|
| + this.anchorIndex_ = ai;
|
| + cr.dispatchPropertyChange(this, 'anchorIndex', ai, oldAnchorIndex);
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * 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) {
|
| + var oldLeadIndex = this.leadIndex;
|
| +
|
| + var oldSelectedIndexes = this.selectedIndexes;
|
| + this.selectedIndexes = oldSelectedIndexes.map(function(oldIndex) {
|
| + return permutation[oldIndex];
|
| + }).filter(function(index) {
|
| + return index != -1;
|
| + });
|
| +
|
| + if (oldLeadIndex != -1)
|
| + this.leadIndex = permutation[oldLeadIndex];
|
| + },
|
| +
|
| + /**
|
| + * Adjusts selection model length.
|
| + * @param {number} length New selection model length.
|
| + */
|
| + adjustLength: function(length) {
|
| + this.length_ = length;
|
| + }
|
| + };
|
| +
|
| + return {
|
| + ListSelectionModel: ListSelectionModel
|
| + };
|
| +});
|
|
|