| Index: chrome/browser/resources/shared/js/cr/ui/table.js
|
| ===================================================================
|
| --- chrome/browser/resources/shared/js/cr/ui/table.js (revision 177292)
|
| +++ chrome/browser/resources/shared/js/cr/ui/table.js (working copy)
|
| @@ -1,379 +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.
|
| -
|
| -/**
|
| - * @fileoverview This implements a table control.
|
| - */
|
| -
|
| -cr.define('cr.ui', function() {
|
| - /** @const */ var ListSelectionModel = cr.ui.ListSelectionModel;
|
| - /** @const */ var ListSelectionController = cr.ui.ListSelectionController;
|
| - /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
|
| - /** @const */ var TableColumnModel = cr.ui.table.TableColumnModel;
|
| - /** @const */ var TableList = cr.ui.table.TableList;
|
| - /** @const */ var TableHeader = cr.ui.table.TableHeader;
|
| -
|
| - /**
|
| - * Creates a new table element.
|
| - * @param {Object=} opt_propertyBag Optional properties.
|
| - * @constructor
|
| - * @extends {HTMLDivElement}
|
| - */
|
| - var Table = cr.ui.define('div');
|
| -
|
| - Table.prototype = {
|
| - __proto__: HTMLDivElement.prototype,
|
| -
|
| - columnModel_: new TableColumnModel([]),
|
| -
|
| - /**
|
| - * The table data model.
|
| - *
|
| - * @type {cr.ui.ArrayDataModel}
|
| - */
|
| - get dataModel() {
|
| - return this.list_.dataModel;
|
| - },
|
| - set dataModel(dataModel) {
|
| - if (this.list_.dataModel != dataModel) {
|
| - if (this.list_.dataModel) {
|
| - this.list_.dataModel.removeEventListener('sorted',
|
| - this.boundHandleSorted_);
|
| - this.list_.dataModel.removeEventListener('change',
|
| - this.boundHandleChangeList_);
|
| - this.list_.dataModel.removeEventListener('splice',
|
| - this.boundHandleChangeList_);
|
| - }
|
| - this.list_.dataModel = dataModel;
|
| - if (this.list_.dataModel) {
|
| - this.list_.dataModel.addEventListener('sorted',
|
| - this.boundHandleSorted_);
|
| - this.list_.dataModel.addEventListener('change',
|
| - this.boundHandleChangeList_);
|
| - this.list_.dataModel.addEventListener('splice',
|
| - this.boundHandleChangeList_);
|
| - }
|
| - this.header_.redraw();
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * The list of table.
|
| - *
|
| - * @type {cr.ui.list}
|
| - */
|
| - get list() {
|
| - return this.list_;
|
| - },
|
| -
|
| - /**
|
| - * The table column model.
|
| - *
|
| - * @type {cr.ui.table.TableColumnModel}
|
| - */
|
| - get columnModel() {
|
| - return this.columnModel_;
|
| - },
|
| - set columnModel(columnModel) {
|
| - if (this.columnModel_ != columnModel) {
|
| - if (this.columnModel_)
|
| - this.columnModel_.removeEventListener('resize', this.boundResize_);
|
| - this.columnModel_ = columnModel;
|
| -
|
| - if (this.columnModel_)
|
| - this.columnModel_.addEventListener('resize', this.boundResize_);
|
| - this.list_.invalidate();
|
| - this.redraw();
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * The table selection model.
|
| - *
|
| - * @type
|
| - * {cr.ui.ListSelectionModel|cr.ui.table.ListSingleSelectionModel}
|
| - */
|
| - get selectionModel() {
|
| - return this.list_.selectionModel;
|
| - },
|
| - set selectionModel(selectionModel) {
|
| - if (this.list_.selectionModel != selectionModel) {
|
| - if (this.dataModel)
|
| - selectionModel.adjustLength(this.dataModel.length);
|
| - this.list_.selectionModel = selectionModel;
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * The accessor to "autoExpands" property of the list.
|
| - *
|
| - * @type {boolean}
|
| - */
|
| - get autoExpands() {
|
| - return this.list_.autoExpands;
|
| - },
|
| - set autoExpands(autoExpands) {
|
| - this.list_.autoExpands = autoExpands;
|
| - },
|
| -
|
| - get fixedHeight() {
|
| - return this.list_.fixedHeight;
|
| - },
|
| - set fixedHeight(fixedHeight) {
|
| - this.list_.fixedHeight = fixedHeight;
|
| - },
|
| -
|
| - /**
|
| - * Returns render function for row.
|
| - * @return {Function(*, cr.ui.Table): HTMLElement} Render function.
|
| - */
|
| - getRenderFunction: function() {
|
| - return this.list_.renderFunction_;
|
| - },
|
| -
|
| - /**
|
| - * Sets render function for row.
|
| - * @param {Function(*, cr.ui.Table): HTMLElement} Render function.
|
| - */
|
| - setRenderFunction: function(renderFunction) {
|
| - if (renderFunction === this.list_.renderFunction_)
|
| - return;
|
| -
|
| - this.list_.renderFunction_ = renderFunction;
|
| - cr.dispatchSimpleEvent(this, 'change');
|
| - },
|
| -
|
| - /**
|
| - * The header of the table.
|
| - *
|
| - * @type {cr.ui.table.TableColumnModel}
|
| - */
|
| - get header() {
|
| - return this.header_;
|
| - },
|
| -
|
| - /**
|
| - * Initializes the element.
|
| - */
|
| - decorate: function() {
|
| - this.header_ = this.ownerDocument.createElement('div');
|
| - this.list_ = this.ownerDocument.createElement('list');
|
| -
|
| - this.appendChild(this.header_);
|
| - this.appendChild(this.list_);
|
| -
|
| - TableList.decorate(this.list_);
|
| - this.list_.selectionModel = new ListSelectionModel(this);
|
| - this.list_.table = this;
|
| - this.list_.addEventListener('scroll', this.handleScroll_.bind(this));
|
| -
|
| - TableHeader.decorate(this.header_);
|
| - this.header_.table = this;
|
| -
|
| - this.classList.add('table');
|
| -
|
| - this.boundResize_ = this.resize.bind(this);
|
| - this.boundHandleSorted_ = this.handleSorted_.bind(this);
|
| - this.boundHandleChangeList_ = this.handleChangeList_.bind(this);
|
| -
|
| - // The contained list should be focusable, not the table itself.
|
| - if (this.hasAttribute('tabindex')) {
|
| - this.list_.setAttribute('tabindex', this.getAttribute('tabindex'));
|
| - this.removeAttribute('tabindex');
|
| - }
|
| -
|
| - this.addEventListener('focus', this.handleElementFocus_, true);
|
| - this.addEventListener('blur', this.handleElementBlur_, true);
|
| - },
|
| -
|
| - /**
|
| - * Redraws the table.
|
| - */
|
| - redraw: function(index) {
|
| - this.list_.redraw();
|
| - this.header_.redraw();
|
| - },
|
| -
|
| - startBatchUpdates: function() {
|
| - this.list_.startBatchUpdates();
|
| - this.header_.startBatchUpdates();
|
| - },
|
| -
|
| - endBatchUpdates: function() {
|
| - this.list_.endBatchUpdates();
|
| - this.header_.endBatchUpdates();
|
| - },
|
| -
|
| - /**
|
| - * Resize the table columns.
|
| - */
|
| - resize: function() {
|
| - // We resize columns only instead of full redraw.
|
| - this.list_.resize();
|
| - this.header_.resize();
|
| - },
|
| -
|
| - /**
|
| - * Ensures that a given index is inside the viewport.
|
| - * @param {number} index The index of the item to scroll into view.
|
| - * @return {boolean} Whether any scrolling was needed.
|
| - */
|
| - scrollIndexIntoView: function(i) {
|
| - this.list_.scrollIndexIntoView(i);
|
| - },
|
| -
|
| - /**
|
| - * Find the list item element at the given index.
|
| - * @param {number} index The index of the list item to get.
|
| - * @return {ListItem} The found list item or null if not found.
|
| - */
|
| - getListItemByIndex: function(index) {
|
| - return this.list_.getListItemByIndex(index);
|
| - },
|
| -
|
| - /**
|
| - * This handles data model 'sorted' event.
|
| - * After sorting we need to redraw header
|
| - * @param {Event} e The 'sorted' event.
|
| - */
|
| - handleSorted_: function(e) {
|
| - this.header_.redraw();
|
| - },
|
| -
|
| - /**
|
| - * This handles data model 'change' and 'splice' events.
|
| - * Since they may change the visibility of scrollbar, table may need to
|
| - * re-calculation the width of column headers.
|
| - * @param {Event} e The 'change' or 'splice' event.
|
| - */
|
| - handleChangeList_: function(e) {
|
| - webkitRequestAnimationFrame(this.header_.updateWidth.bind(this.header_));
|
| - },
|
| -
|
| - /**
|
| - * This handles list 'scroll' events. Scrolls the header accordingly.
|
| - * @param {Event} e Scroll event.
|
| - */
|
| - handleScroll_: function(e) {
|
| - this.header_.style.marginLeft = -this.list_.scrollLeft + 'px';
|
| - },
|
| -
|
| - /**
|
| - * Sort data by the given column.
|
| - * @param {number} index The index of the column to sort by.
|
| - */
|
| - sort: function(i) {
|
| - var cm = this.columnModel_;
|
| - var sortStatus = this.list_.dataModel.sortStatus;
|
| - if (sortStatus.field == cm.getId(i)) {
|
| - var sortDirection = sortStatus.direction == 'desc' ? 'asc' : 'desc';
|
| - this.list_.dataModel.sort(sortStatus.field, sortDirection);
|
| - } else {
|
| - this.list_.dataModel.sort(cm.getId(i), cm.getDefaultOrder(i));
|
| - }
|
| - if (this.selectionModel.selectedIndex == -1)
|
| - this.list_.scrollTop = 0;
|
| - },
|
| -
|
| - /**
|
| - * Called when an element in the table is focused. Marks the table as having
|
| - * a focused element, and dispatches an event if it didn't have focus.
|
| - * @param {Event} e The focus event.
|
| - * @private
|
| - */
|
| - handleElementFocus_: function(e) {
|
| - if (!this.hasElementFocus) {
|
| - this.hasElementFocus = true;
|
| - // Force styles based on hasElementFocus to take effect.
|
| - this.list_.redraw();
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * Called when an element in the table is blurred. If focus moves outside
|
| - * the table, marks the table as no longer having focus and dispatches an
|
| - * event.
|
| - * @param {Event} e The blur event.
|
| - * @private
|
| - */
|
| - handleElementBlur_: function(e) {
|
| - // When the blur event happens we do not know who is getting focus so we
|
| - // delay this a bit until we know if the new focus node is outside the
|
| - // table.
|
| - var table = this;
|
| - var list = this.list_;
|
| - var doc = e.target.ownerDocument;
|
| - window.setTimeout(function() {
|
| - var activeElement = doc.activeElement;
|
| - if (!table.contains(activeElement)) {
|
| - table.hasElementFocus = false;
|
| - // Force styles based on hasElementFocus to take effect.
|
| - list.redraw();
|
| - }
|
| - });
|
| - },
|
| -
|
| - /**
|
| - * Adjust column width to fit its content.
|
| - * @param {number} index Index of the column to adjust width.
|
| - */
|
| - fitColumn: function(index) {
|
| - var list = this.list_;
|
| - var listHeight = list.clientHeight;
|
| -
|
| - var cm = this.columnModel_;
|
| - var dm = this.dataModel;
|
| - var columnId = cm.getId(index);
|
| - var doc = this.ownerDocument;
|
| - var render = cm.getRenderFunction(index);
|
| - var table = this;
|
| - var MAXIMUM_ROWS_TO_MEASURE = 1000;
|
| -
|
| - // Create a temporaty list item, put all cells into it and measure its
|
| - // width. Then remove the item. It fits "list > *" CSS rules.
|
| - var container = doc.createElement('li');
|
| - container.style.display = 'inline-block';
|
| - container.style.textAlign = 'start';
|
| - // The container will have width of the longest cell.
|
| - container.style.webkitBoxOrient = 'vertical';
|
| -
|
| - // Ensure all needed data available.
|
| - dm.prepareSort(columnId, function() {
|
| - // Select at most MAXIMUM_ROWS_TO_MEASURE items around visible area.
|
| - var items = list.getItemsInViewPort(list.scrollTop, listHeight);
|
| - var firstIndex = Math.floor(Math.max(0,
|
| - (items.last + items.first - MAXIMUM_ROWS_TO_MEASURE) / 2));
|
| - var lastIndex = Math.min(dm.length,
|
| - firstIndex + MAXIMUM_ROWS_TO_MEASURE);
|
| - for (var i = firstIndex; i < lastIndex; i++) {
|
| - var item = dm.item(i);
|
| - var div = doc.createElement('div');
|
| - div.className = 'table-row-cell';
|
| - div.appendChild(render(item, columnId, table));
|
| - container.appendChild(div);
|
| - }
|
| - list.appendChild(container);
|
| - var width = parseFloat(getComputedStyle(container).width);
|
| - list.removeChild(container);
|
| - cm.setWidth(index, width);
|
| - });
|
| - },
|
| -
|
| - normalizeColumns: function() {
|
| - this.columnModel.normalizeWidths(this.clientWidth);
|
| - }
|
| - };
|
| -
|
| - /**
|
| - * Whether the table or one of its descendents has focus. This is necessary
|
| - * because table contents can contain controls that can be focused, and for
|
| - * some purposes (e.g., styling), the table can still be conceptually focused
|
| - * at that point even though it doesn't actually have the page focus.
|
| - */
|
| - cr.defineProperty(Table, 'hasElementFocus', cr.PropertyKind.BOOL_ATTR);
|
| -
|
| - return {
|
| - Table: Table
|
| - };
|
| -});
|
|
|