OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. | 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 21 matching lines...) Expand all Loading... |
32 * @param {function()=} refreshCallback | 32 * @param {function()=} refreshCallback |
33 * @param {function(!WebInspector.ContextMenu, !WebInspector.DataGridNode)=} con
textMenuCallback | 33 * @param {function(!WebInspector.ContextMenu, !WebInspector.DataGridNode)=} con
textMenuCallback |
34 */ | 34 */ |
35 WebInspector.DataGrid = function(columnsArray, editCallback, deleteCallback, ref
reshCallback, contextMenuCallback) | 35 WebInspector.DataGrid = function(columnsArray, editCallback, deleteCallback, ref
reshCallback, contextMenuCallback) |
36 { | 36 { |
37 this.element = createElementWithClass("div", "data-grid"); | 37 this.element = createElementWithClass("div", "data-grid"); |
38 WebInspector.appendStyle(this.element, "ui_lazy/dataGrid.css"); | 38 WebInspector.appendStyle(this.element, "ui_lazy/dataGrid.css"); |
39 this.element.tabIndex = 0; | 39 this.element.tabIndex = 0; |
40 this.element.addEventListener("keydown", this._keyDown.bind(this), false); | 40 this.element.addEventListener("keydown", this._keyDown.bind(this), false); |
41 | 41 |
42 var headerContainer = createElementWithClass("div", "header-container"); | |
43 /** @type {!Element} */ | |
44 this._headerTable = headerContainer.createChild("table", "header"); | |
45 /** @type {!Object.<string, !Element>} */ | |
46 this._headerTableHeaders = {}; | |
47 | |
48 /** @type {!Element} */ | |
49 this._scrollContainer = createElementWithClass("div", "data-container"); | |
50 /** @type {!Element} */ | |
51 this._dataTable = this._scrollContainer.createChild("table", "data"); | |
52 | |
53 this._dataTable.addEventListener("mousedown", this._mouseDownInDataTable.bin
d(this)); | |
54 this._dataTable.addEventListener("click", this._clickInDataTable.bind(this),
true); | |
55 | |
56 this._dataTable.addEventListener("contextmenu", this._contextMenuInDataTable
.bind(this), true); | |
57 | |
58 // FIXME: Add a createCallback which is different from editCallback and has
different | |
59 // behavior when creating a new node. | |
60 if (editCallback) | |
61 this._dataTable.addEventListener("dblclick", this._ondblclick.bind(this)
, false); | |
62 /** @type {function(!WebInspector.DataGridNode, string, string, string)|unde
fined} */ | 42 /** @type {function(!WebInspector.DataGridNode, string, string, string)|unde
fined} */ |
63 this._editCallback = editCallback; | 43 this._editCallback = editCallback; |
64 /** @type {function(!WebInspector.DataGridNode)|undefined} */ | 44 /** @type {function(!WebInspector.DataGridNode)|undefined} */ |
65 this._deleteCallback = deleteCallback; | 45 this._deleteCallback = deleteCallback; |
66 /** @type {function()|undefined} */ | 46 /** @type {function()|undefined} */ |
67 this._refreshCallback = refreshCallback; | 47 this._refreshCallback = refreshCallback; |
68 /** @type {function(!WebInspector.ContextMenu, !WebInspector.DataGridNode)|u
ndefined} */ | 48 /** @type {function(!WebInspector.ContextMenu, !WebInspector.DataGridNode)|u
ndefined} */ |
69 this._contextMenuCallback = contextMenuCallback; | 49 this._contextMenuCallback = contextMenuCallback; |
70 | 50 |
71 this.element.appendChild(headerContainer); | 51 var headerContainer = this.element.createChild("div", "header-container"); |
72 this.element.appendChild(this._scrollContainer); | 52 /** @type {!Element} */ |
| 53 this._headerTable = headerContainer.createChild("table", "header"); |
| 54 /** @type {!Object.<string, !Element>} */ |
| 55 this._headerTableHeaders = {}; |
| 56 /** @type {!Element} */ |
| 57 this._scrollContainer = this.element.createChild("div", "data-container"); |
| 58 /** @type {!Element} */ |
| 59 this._dataTable = this._scrollContainer.createChild("table", "data"); |
73 | 60 |
74 /** @type {!Element} */ | 61 // FIXME: Add a createCallback which is different from editCallback and has
different |
75 this._headerRow = createElement("tr"); | 62 // behavior when creating a new node. |
76 /** @type {!Element} */ | 63 if (editCallback) |
77 this._headerTableColumnGroup = createElement("colgroup"); | 64 this._dataTable.addEventListener("dblclick", this._ondblclick.bind(this)
, false); |
78 /** @type {!Element} */ | 65 this._dataTable.addEventListener("mousedown", this._mouseDownInDataTable.bin
d(this)); |
79 this._dataTableColumnGroup = createElement("colgroup"); | 66 this._dataTable.addEventListener("click", this._clickInDataTable.bind(this),
true); |
80 | 67 this._dataTable.addEventListener("contextmenu", this._contextMenuInDataTable
.bind(this), true); |
81 /** @type {!Element} */ | |
82 this._topFillerRow = createElementWithClass("tr", "data-grid-filler-row reve
aled"); | |
83 /** @type {!Element} */ | |
84 this._bottomFillerRow = createElementWithClass("tr", "data-grid-filler-row r
evealed"); | |
85 this.setVerticalPadding(0, 0); | |
86 | 68 |
87 /** @type {boolean} */ | 69 /** @type {boolean} */ |
88 this._inline = false; | 70 this._inline = false; |
89 | 71 |
90 /** @type {!Array.<!WebInspector.DataGrid.ColumnDescriptor>} */ | 72 /** @type {!Array.<!WebInspector.DataGrid.ColumnDescriptor>} */ |
91 this._columnsArray = []; | 73 this._columnsArray = []; |
92 /** @type {!Object.<string, !WebInspector.DataGrid.ColumnDescriptor>} */ | 74 /** @type {!Object.<string, !WebInspector.DataGrid.ColumnDescriptor>} */ |
93 this._columns = {}; | 75 this._columns = {}; |
94 /** @type {!Array.<!WebInspector.DataGrid.ColumnDescriptor>} */ | 76 /** @type {!Array.<!WebInspector.DataGrid.ColumnDescriptor>} */ |
95 this._visibleColumnsArray = columnsArray; | 77 this._visibleColumnsArray = columnsArray; |
96 | 78 |
97 columnsArray.forEach(column => this._innerAddColumn(column)); | 79 columnsArray.forEach(column => this._innerAddColumn(column)); |
98 | 80 |
99 /** @type {?string} */ | 81 /** @type {?string} */ |
100 this._cellClass = null; | 82 this._cellClass = null; |
101 | 83 |
102 this._headerTable.appendChild(this._headerTableColumnGroup); | 84 /** @type {!Element} */ |
103 this.headerTableBody.appendChild(this._headerRow); | 85 this._headerTableColumnGroup = this._headerTable.createChild("colgroup"); |
| 86 /** @type {!Element} */ |
| 87 this._headerTableBody = this._headerTable.createChild("tbody"); |
| 88 /** @type {!Element} */ |
| 89 this._headerRow = this._headerTableBody.createChild("tr"); |
104 | 90 |
105 this._dataTable.appendChild(this._dataTableColumnGroup); | 91 /** @type {!Element} */ |
106 this.dataTableBody.appendChild(this._topFillerRow); | 92 this._dataTableColumnGroup = this._dataTable.createChild("colgroup"); |
107 this.dataTableBody.appendChild(this._bottomFillerRow); | 93 /** |
| 94 * @protected |
| 95 * @type {!Element} |
| 96 */ |
| 97 this.dataTableBody = this._dataTable.createChild("tbody"); |
| 98 /** @type {!Element} */ |
| 99 this._topFillerRow = this.dataTableBody.createChild("tr", "data-grid-filler-
row revealed"); |
| 100 /** @type {!Element} */ |
| 101 this._bottomFillerRow = this.dataTableBody.createChild("tr", "data-grid-fill
er-row revealed"); |
108 | 102 |
| 103 this.setVerticalPadding(0, 0); |
109 this._refreshHeader(); | 104 this._refreshHeader(); |
110 | 105 |
111 /** @type {boolean} */ | 106 /** @type {boolean} */ |
112 this._editing = false; | 107 this._editing = false; |
113 /** @type {?WebInspector.DataGridNode} */ | 108 /** @type {?WebInspector.DataGridNode} */ |
114 this.selectedNode = null; | 109 this.selectedNode = null; |
115 /** @type {boolean} */ | 110 /** @type {boolean} */ |
116 this.expandNodesWhenArrowing = false; | 111 this.expandNodesWhenArrowing = false; |
117 this.setRootNode(new WebInspector.DataGridNode()); | 112 this.setRootNode(new WebInspector.DataGridNode()); |
118 /** @type {number} */ | 113 /** @type {number} */ |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 /** @enum {string} */ | 162 /** @enum {string} */ |
168 WebInspector.DataGrid.Align = { | 163 WebInspector.DataGrid.Align = { |
169 Center: "center", | 164 Center: "center", |
170 Right: "right" | 165 Right: "right" |
171 } | 166 } |
172 | 167 |
173 WebInspector.DataGrid._preferredWidthSymbol = Symbol("preferredWidth"); | 168 WebInspector.DataGrid._preferredWidthSymbol = Symbol("preferredWidth"); |
174 | 169 |
175 WebInspector.DataGrid.prototype = { | 170 WebInspector.DataGrid.prototype = { |
176 /** | 171 /** |
| 172 * @return {!Element} |
| 173 */ |
| 174 headerTableBody: function() |
| 175 { |
| 176 return this._headerTableBody; |
| 177 }, |
| 178 |
| 179 /** |
177 * @param {!WebInspector.DataGrid.ColumnDescriptor} column | 180 * @param {!WebInspector.DataGrid.ColumnDescriptor} column |
178 * @param {number=} position | 181 * @param {number=} position |
179 */ | 182 */ |
180 _innerAddColumn: function(column, position) | 183 _innerAddColumn: function(column, position) |
181 { | 184 { |
182 var columnIdentifier = column.identifier = column.id || String(Object.ke
ys(this._columns).length); | 185 var columnIdentifier = column.identifier = column.id || String(Object.ke
ys(this._columns).length); |
183 if (columnIdentifier in this._columns) | 186 if (columnIdentifier in this._columns) |
184 this._innerRemoveColumn(columnIdentifier); | 187 this._innerRemoveColumn(columnIdentifier); |
185 | 188 |
186 if (position === undefined) | 189 if (position === undefined) |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 }, | 514 }, |
512 | 515 |
513 /** | 516 /** |
514 * @return {boolean} | 517 * @return {boolean} |
515 */ | 518 */ |
516 isSortOrderAscending: function() | 519 isSortOrderAscending: function() |
517 { | 520 { |
518 return !this._sortColumnCell || this._sortColumnCell.classList.contains(
WebInspector.DataGrid.Order.Ascending); | 521 return !this._sortColumnCell || this._sortColumnCell.classList.contains(
WebInspector.DataGrid.Order.Ascending); |
519 }, | 522 }, |
520 | 523 |
521 get headerTableBody() | |
522 { | |
523 if ("_headerTableBody" in this) | |
524 return this._headerTableBody; | |
525 | |
526 this._headerTableBody = this._headerTable.getElementsByTagName("tbody")[
0]; | |
527 if (!this._headerTableBody) { | |
528 this._headerTableBody = this.element.ownerDocument.createElement("tb
ody"); | |
529 this._headerTable.insertBefore(this._headerTableBody, this._headerTa
ble.tFoot); | |
530 } | |
531 | |
532 return this._headerTableBody; | |
533 }, | |
534 | |
535 get dataTableBody() | |
536 { | |
537 if ("_dataTableBody" in this) | |
538 return this._dataTableBody; | |
539 | |
540 this._dataTableBody = this._dataTable.getElementsByTagName("tbody")[0]; | |
541 if (!this._dataTableBody) { | |
542 this._dataTableBody = this.element.ownerDocument.createElement("tbod
y"); | |
543 this._dataTable.insertBefore(this._dataTableBody, this._dataTable.tF
oot); | |
544 } | |
545 | |
546 return this._dataTableBody; | |
547 }, | |
548 | |
549 /** | 524 /** |
550 * @param {!Array.<number>} widths | 525 * @param {!Array.<number>} widths |
551 * @param {number} minPercent | 526 * @param {number} minPercent |
552 * @param {number=} maxPercent | 527 * @param {number=} maxPercent |
553 * @return {!Array.<number>} | 528 * @return {!Array.<number>} |
554 */ | 529 */ |
555 _autoSizeWidths: function(widths, minPercent, maxPercent) | 530 _autoSizeWidths: function(widths, minPercent, maxPercent) |
556 { | 531 { |
557 if (minPercent) | 532 if (minPercent) |
558 minPercent = Math.min(minPercent, Math.floor(100 / widths.length)); | 533 minPercent = Math.min(minPercent, Math.floor(100 / widths.length)); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 // | 622 // |
648 // IMPORTANT: This function MUST be called once after the element of the | 623 // IMPORTANT: This function MUST be called once after the element of the |
649 // DataGrid is attached to its parent element and every subsequent time the | 624 // DataGrid is attached to its parent element and every subsequent time the |
650 // width of the parent element is changed in order to make it possible to | 625 // width of the parent element is changed in order to make it possible to |
651 // resize the columns. | 626 // resize the columns. |
652 // | 627 // |
653 // If this function is not called after the DataGrid is attached to its | 628 // If this function is not called after the DataGrid is attached to its |
654 // parent element, then the DataGrid's columns will not be resizable. | 629 // parent element, then the DataGrid's columns will not be resizable. |
655 updateWidths: function() | 630 updateWidths: function() |
656 { | 631 { |
657 var headerTableColumns = this._headerTableColumnGroup.children; | |
658 | |
659 // Use container size to avoid changes of table width caused by change o
f column widths. | |
660 var tableWidth = this.element.offsetWidth - this._cornerWidth; | |
661 var numColumns = headerTableColumns.length - 1; // Do not process corner
column. | |
662 | |
663 // Do not attempt to use offsetes if we're not attached to the document
tree yet. | 632 // Do not attempt to use offsetes if we're not attached to the document
tree yet. |
664 if (!this._columnWidthsInitialized && this.element.offsetWidth) { | 633 if (!this._columnWidthsInitialized && this.element.offsetWidth) { |
665 // Give all the columns initial widths now so that during a resize, | 634 // Give all the columns initial widths now so that during a resize, |
666 // when the two columns that get resized get a percent value for | 635 // when the two columns that get resized get a percent value for |
667 // their widths, all the other columns already have percent values | 636 // their widths, all the other columns already have percent values |
668 // for their widths. | 637 // for their widths. |
| 638 var headerTableColumns = this._headerTableColumnGroup.children; |
| 639 |
| 640 // Use container size to avoid changes of table width caused by chan
ge of column widths. |
| 641 var tableWidth = this.element.offsetWidth - this._cornerWidth; |
| 642 var cells = this._headerTableBody.rows[0].cells; |
| 643 var numColumns = cells.length - 1; // Do not process corner column. |
669 for (var i = 0; i < numColumns; i++) { | 644 for (var i = 0; i < numColumns; i++) { |
670 var columnWidth = this.headerTableBody.rows[0].cells[i].offsetWi
dth; | |
671 var column = this._visibleColumnsArray[i]; | 645 var column = this._visibleColumnsArray[i]; |
672 if (!column.weight) | 646 if (!column.weight) |
673 column.weight = 100 * columnWidth / tableWidth; | 647 column.weight = 100 * cells[i].offsetWidth / tableWidth; |
674 } | 648 } |
675 this._columnWidthsInitialized = true; | 649 this._columnWidthsInitialized = true; |
676 } | 650 } |
677 this._applyColumnWeights(); | 651 this._applyColumnWeights(); |
678 }, | 652 }, |
679 | 653 |
680 /** | 654 /** |
681 * @param {string} name | 655 * @param {string} name |
682 */ | 656 */ |
683 setName: function(name) | 657 setName: function(name) |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
725 { | 699 { |
726 var tableWidth = this.element.offsetWidth - this._cornerWidth; | 700 var tableWidth = this.element.offsetWidth - this._cornerWidth; |
727 if (tableWidth <= 0) | 701 if (tableWidth <= 0) |
728 return; | 702 return; |
729 | 703 |
730 var sumOfWeights = 0.0; | 704 var sumOfWeights = 0.0; |
731 var fixedColumnWidths = []; | 705 var fixedColumnWidths = []; |
732 for (var i = 0; i < this._visibleColumnsArray.length; ++i) { | 706 for (var i = 0; i < this._visibleColumnsArray.length; ++i) { |
733 var column = this._visibleColumnsArray[i]; | 707 var column = this._visibleColumnsArray[i]; |
734 if (column.fixedWidth) { | 708 if (column.fixedWidth) { |
735 var width = this._headerTableColumnGroup.children[i][WebInspecto
r.DataGrid._preferredWidthSymbol] || this.headerTableBody.rows[0].cells[i].offse
tWidth; | 709 var width = this._headerTableColumnGroup.children[i][WebInspecto
r.DataGrid._preferredWidthSymbol] || this._headerTableBody.rows[0].cells[i].offs
etWidth; |
736 fixedColumnWidths[i] = width; | 710 fixedColumnWidths[i] = width; |
737 tableWidth -= width; | 711 tableWidth -= width; |
738 } else { | 712 } else { |
739 sumOfWeights += this._visibleColumnsArray[i].weight; | 713 sumOfWeights += this._visibleColumnsArray[i].weight; |
740 } | 714 } |
741 } | 715 } |
742 var sum = 0; | 716 var sum = 0; |
743 var lastOffset = 0; | 717 var lastOffset = 0; |
744 | 718 |
745 for (var i = 0; i < this._visibleColumnsArray.length; ++i) { | 719 for (var i = 0; i < this._visibleColumnsArray.length; ++i) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
790 var left = []; | 764 var left = []; |
791 var resizers = this._resizers; | 765 var resizers = this._resizers; |
792 | 766 |
793 while (resizers.length > numColumns - 1) | 767 while (resizers.length > numColumns - 1) |
794 resizers.pop().remove(); | 768 resizers.pop().remove(); |
795 | 769 |
796 for (var i = 0; i < numColumns - 1; i++) { | 770 for (var i = 0; i < numColumns - 1; i++) { |
797 // Get the width of the cell in the first (and only) row of the | 771 // Get the width of the cell in the first (and only) row of the |
798 // header table in order to determine the width of the column, since | 772 // header table in order to determine the width of the column, since |
799 // it is not possible to query a column for its width. | 773 // it is not possible to query a column for its width. |
800 left[i] = (left[i - 1] || 0) + this.headerTableBody.rows[0].cells[i]
.offsetWidth; | 774 left[i] = (left[i - 1] || 0) + this._headerTableBody.rows[0].cells[i
].offsetWidth; |
801 } | 775 } |
802 | 776 |
803 // Make n - 1 resizers for n columns. | 777 // Make n - 1 resizers for n columns. |
804 for (var i = 0; i < numColumns - 1; i++) { | 778 for (var i = 0; i < numColumns - 1; i++) { |
805 var resizer = resizers[i]; | 779 var resizer = resizers[i]; |
806 if (!resizer) { | 780 if (!resizer) { |
807 // This is the first call to updateWidth, so the resizers need | 781 // This is the first call to updateWidth, so the resizers need |
808 // to be created. | 782 // to be created. |
809 resizer = createElement("div"); | 783 resizer = createElement("div"); |
810 resizer.__index = i; | 784 resizer.__index = i; |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1085 | 1059 |
1086 _resizerDragging: function(event) | 1060 _resizerDragging: function(event) |
1087 { | 1061 { |
1088 var resizer = this._currentResizer; | 1062 var resizer = this._currentResizer; |
1089 if (!resizer) | 1063 if (!resizer) |
1090 return; | 1064 return; |
1091 | 1065 |
1092 // Constrain the dragpoint to be within the containing div of the | 1066 // Constrain the dragpoint to be within the containing div of the |
1093 // datagrid. | 1067 // datagrid. |
1094 var dragPoint = event.clientX - this.element.totalOffsetLeft(); | 1068 var dragPoint = event.clientX - this.element.totalOffsetLeft(); |
1095 var firstRowCells = this.headerTableBody.rows[0].cells; | 1069 var firstRowCells = this._headerTableBody.rows[0].cells; |
1096 var leftEdgeOfPreviousColumn = 0; | 1070 var leftEdgeOfPreviousColumn = 0; |
1097 // Constrain the dragpoint to be within the space made up by the | 1071 // Constrain the dragpoint to be within the space made up by the |
1098 // column directly to the left and the column directly to the right. | 1072 // column directly to the left and the column directly to the right. |
1099 var leftCellIndex = resizer.__index; | 1073 var leftCellIndex = resizer.__index; |
1100 var rightCellIndex = leftCellIndex + 1; | 1074 var rightCellIndex = leftCellIndex + 1; |
1101 for (var i = 0; i < leftCellIndex; i++) | 1075 for (var i = 0; i < leftCellIndex; i++) |
1102 leftEdgeOfPreviousColumn += firstRowCells[i].offsetWidth; | 1076 leftEdgeOfPreviousColumn += firstRowCells[i].offsetWidth; |
1103 | 1077 |
1104 // Differences for other resize methods | 1078 // Differences for other resize methods |
1105 if (this._resizeMethod === WebInspector.DataGrid.ResizeMethod.Last) { | 1079 if (this._resizeMethod === WebInspector.DataGrid.ResizeMethod.Last) { |
(...skipping 856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1962 detachChildWidgets: function() | 1936 detachChildWidgets: function() |
1963 { | 1937 { |
1964 WebInspector.Widget.prototype.detachChildWidgets.call(this); | 1938 WebInspector.Widget.prototype.detachChildWidgets.call(this); |
1965 for (var dataGrid of this._dataGrids) | 1939 for (var dataGrid of this._dataGrids) |
1966 this.element.removeChild(dataGrid.element); | 1940 this.element.removeChild(dataGrid.element); |
1967 this._dataGrids = []; | 1941 this._dataGrids = []; |
1968 }, | 1942 }, |
1969 | 1943 |
1970 __proto__: WebInspector.VBox.prototype | 1944 __proto__: WebInspector.VBox.prototype |
1971 } | 1945 } |
OLD | NEW |