Home | History | Annotate | Download | only in ui
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 /**
      6  * @constructor
      7  * @extends {WebInspector.ViewportDataGrid}
      8  * @param {!Array.<!WebInspector.DataGrid.ColumnDescriptor>} columnsArray
      9  * @param {function(!WebInspector.DataGridNode, string, string, string)=} editCallback
     10  * @param {function(!WebInspector.DataGridNode)=} deleteCallback
     11  * @param {function()=} refreshCallback
     12  * @param {function(!WebInspector.ContextMenu, !WebInspector.DataGridNode)=} contextMenuCallback
     13  */
     14 WebInspector.SortableDataGrid = function(columnsArray, editCallback, deleteCallback, refreshCallback, contextMenuCallback)
     15 {
     16     WebInspector.ViewportDataGrid.call(this, columnsArray, editCallback, deleteCallback, refreshCallback, contextMenuCallback);
     17     /** @type {!WebInspector.SortableDataGrid.NodeComparator} */
     18     this._sortingFunction = WebInspector.SortableDataGrid.TrivialComparator;
     19     this.setRootNode(new WebInspector.SortableDataGridNode());
     20 }
     21 
     22 /** @typedef {function(!WebInspector.DataGridNode, !WebInspector.DataGridNode):number} */
     23 WebInspector.SortableDataGrid.NodeComparator;
     24 
     25 /**
     26  * @param {!WebInspector.DataGridNode} a
     27  * @param {!WebInspector.DataGridNode} b
     28  * @return {number}
     29  */
     30 WebInspector.SortableDataGrid.TrivialComparator = function(a, b)
     31 {
     32     return 0;
     33 }
     34 
     35 /**
     36  * @param {string} columnIdentifier
     37  * @param {!WebInspector.DataGridNode} a
     38  * @param {!WebInspector.DataGridNode} b
     39  * @return {number}
     40  */
     41 WebInspector.SortableDataGrid.NumericComparator = function(columnIdentifier, a, b)
     42 {
     43     var aValue = a.data[columnIdentifier];
     44     var bValue = b.data[columnIdentifier];
     45     var aNumber = Number(aValue instanceof Node ? aValue.textContent : aValue);
     46     var bNumber = Number(bValue instanceof Node ? bValue.textContent : bValue);
     47     return aNumber < bNumber ? -1 : (aNumber > bNumber ? 1 : 0);
     48 }
     49 
     50 /**
     51  * @param {string} columnIdentifier
     52  * @param {!WebInspector.DataGridNode} a
     53  * @param {!WebInspector.DataGridNode} b
     54  * @return {number}
     55  */
     56 WebInspector.SortableDataGrid.StringComparator = function(columnIdentifier, a, b)
     57 {
     58     var aValue = a.data[columnIdentifier];
     59     var bValue = b.data[columnIdentifier];
     60     var aString = aValue instanceof Node ? aValue.textContent : String(aValue);
     61     var bString = bValue instanceof Node ? bValue.textContent : String(bValue);
     62     return aString < bString ? -1 : (aString > bString ? 1 : 0);
     63 }
     64 
     65 /**
     66  * @param {!WebInspector.SortableDataGrid.NodeComparator} comparator
     67  * @param {boolean} reverseMode
     68  * @param {!WebInspector.DataGridNode} a
     69  * @param {!WebInspector.DataGridNode} b
     70  * @return {number}
     71  */
     72 WebInspector.SortableDataGrid.Comparator = function(comparator, reverseMode, a, b)
     73 {
     74     return reverseMode ? comparator(b, a) : comparator(a, b);
     75 }
     76 
     77 /**
     78  * @param {!Array.<string>} columnNames
     79  * @param {!Array.<string>} values
     80  * @return {?WebInspector.SortableDataGrid}
     81  */
     82 WebInspector.SortableDataGrid.create = function(columnNames, values)
     83 {
     84     var numColumns = columnNames.length;
     85     if (!numColumns)
     86         return null;
     87 
     88     var columns = [];
     89     for (var i = 0; i < columnNames.length; ++i)
     90         columns.push({ title: columnNames[i], width: columnNames[i].length, sortable: true });
     91 
     92     var nodes = [];
     93     for (var i = 0; i < values.length / numColumns; ++i) {
     94         var data = {};
     95         for (var j = 0; j < columnNames.length; ++j)
     96             data[j] = values[numColumns * i + j];
     97 
     98         var node = new WebInspector.SortableDataGridNode(data);
     99         node.selectable = false;
    100         nodes.push(node);
    101     }
    102 
    103     var dataGrid = new WebInspector.SortableDataGrid(columns);
    104     var length = nodes.length;
    105     var rootNode = dataGrid.rootNode();
    106     for (var i = 0; i < length; ++i)
    107         rootNode.appendChild(nodes[i]);
    108 
    109     dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged, sortDataGrid);
    110 
    111     function sortDataGrid()
    112     {
    113         var nodes = dataGrid.rootNode().children;
    114         var sortColumnIdentifier = dataGrid.sortColumnIdentifier();
    115         if (!sortColumnIdentifier)
    116             return;
    117 
    118         var columnIsNumeric = true;
    119         for (var i = 0; i < nodes.length; i++) {
    120             var value = nodes[i].data[sortColumnIdentifier];
    121             if (isNaN(value instanceof Node ? value.textContent : value)) {
    122                 columnIsNumeric = false;
    123                 break;
    124             }
    125         }
    126 
    127         var comparator = columnIsNumeric ? WebInspector.SortableDataGrid.NumericComparator : WebInspector.SortableDataGrid.StringComparator;
    128         dataGrid.sortNodes(comparator.bind(null, sortColumnIdentifier), !dataGrid.isSortOrderAscending());
    129     }
    130     return dataGrid;
    131 }
    132 
    133 WebInspector.SortableDataGrid.prototype = {
    134     /**
    135      * @param {!WebInspector.DataGridNode} node
    136      */
    137     insertChild: function(node)
    138     {
    139         var parentNode = this.rootNode();
    140         parentNode.insertChild(node, parentNode.children.upperBound(node, this._sortingFunction));
    141     },
    142 
    143     /**
    144      * @param {!WebInspector.SortableDataGrid.NodeComparator} comparator
    145      * @param {boolean} reverseMode
    146      */
    147     sortNodes: function(comparator, reverseMode)
    148     {
    149         this._sortingFunction = WebInspector.SortableDataGrid.Comparator.bind(null, comparator, reverseMode);
    150         var children = this._rootNode.children;
    151         children.sort(this._sortingFunction);
    152         for (var i = 0; i < children.length; ++i)
    153             children[i].recalculateSiblings(i);
    154         this.scheduleUpdate();
    155     },
    156 
    157     __proto__: WebInspector.ViewportDataGrid.prototype
    158 }
    159 
    160 /**
    161  * @constructor
    162  * @extends {WebInspector.ViewportDataGridNode}
    163  * @param {?Object.<string, *>=} data
    164  */
    165 WebInspector.SortableDataGridNode = function(data)
    166 {
    167     WebInspector.ViewportDataGridNode.call(this, data);
    168 }
    169 
    170 WebInspector.SortableDataGridNode.prototype = {
    171     __proto__: WebInspector.ViewportDataGridNode.prototype
    172 }
    173