Commit 96ad88ab authored by timothy@apple.com's avatar timothy@apple.com

Adds a DataGrid object that is used for multi-column data

and can contain hierarchical content with disclosure arrows.
A lot of DataGrid was copied from treeoutline.js. This change
makes the database views use the DataGrid. It will later be
used by the ProfileView.

Reviewed by Adam Roben.

* page/inspector/DataGrid.js: Added. Most copied from treeoutline.js
and modified to work with table elements.
* page/inspector/DatabaseQueryView.js:
(WebInspector.DatabaseQueryView.prototype._queryFinished):
Call DatabasesPanel.dataGridForResult and adds the inline style to
the DataGrid element.
* page/inspector/DatabaseTableView.js:
(WebInspector.DatabaseTableView.prototype._queryFinished):
Call DatabasesPanel.dataGridForResult.
* page/inspector/DatabasesPanel.js:
(WebInspector.DatabasesPanel.prototype._tableForResult): Removed.
(WebInspector.DatabasesPanel.prototype.dataGridForResult): Added.
Similar to the previous _tableForResult function, but makes a DataGrid.
* page/inspector/inspector.css: Changes to the data-grid
style rules.
* WebCore.vcproj/WebCore.vcproj: Add DataGrid.js.
* page/inspector/WebKit.qrc: Ditto.
* page/inspector/inspector.html: Ditto.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@33927 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 4c3907ae
2008-05-19 Timothy Hatcher <timothy@apple.com>
Adds a DataGrid object that is used for multi-column data
and can contain hierarchical content with disclosure arrows.
A lot of DataGrid was copied from treeoutline.js. This change
makes the database views use the DataGrid. It will later be
used by the ProfileView.
Reviewed by Adam Roben.
* page/inspector/DataGrid.js: Added. Most copied from treeoutline.js
and modified to work with table elements.
* page/inspector/DatabaseQueryView.js:
(WebInspector.DatabaseQueryView.prototype._queryFinished):
Call DatabasesPanel.dataGridForResult and adds the inline style to
the DataGrid element.
* page/inspector/DatabaseTableView.js:
(WebInspector.DatabaseTableView.prototype._queryFinished):
Call DatabasesPanel.dataGridForResult.
* page/inspector/DatabasesPanel.js:
(WebInspector.DatabasesPanel.prototype._tableForResult): Removed.
(WebInspector.DatabasesPanel.prototype.dataGridForResult): Added.
Similar to the previous _tableForResult function, but makes a DataGrid.
* page/inspector/inspector.css: Changes to the data-grid
style rules.
* WebCore.vcproj/WebCore.vcproj: Add DataGrid.js.
* page/inspector/WebKit.qrc: Ditto.
* page/inspector/inspector.html: Ditto.
2008-05-19 Kevin McCullough <kmccullough@apple.com>
Reviewed by Adam.
......@@ -3630,6 +3630,10 @@
RelativePath="..\page\inspector\Database.js"
>
</File>
<File
RelativePath="..\page\inspector\DataGrid.js"
>
</File>
<File
RelativePath="..\page\inspector\DatabaseQueryView.js"
>
......
This diff is collapsed.
......@@ -150,7 +150,9 @@ WebInspector.DatabaseQueryView.prototype = {
_queryFinished: function(query, tx, result)
{
this._appendQueryResult(query, WebInspector.panels.databases._tableForResult(result));
var dataGrid = WebInspector.panels.databases.dataGridForResult(result);
dataGrid.element.addStyleClass("inline");
this._appendQueryResult(query, dataGrid.element);
if (query.match(/^create /i) || query.match(/^drop table /i))
WebInspector.panels.databases.updateDatabaseTables(this.database);
......
......@@ -55,8 +55,8 @@ WebInspector.DatabaseTableView.prototype = {
{
this.element.removeChildren();
var table = WebInspector.panels.databases._tableForResult(result);
if (!table) {
var dataGrid = WebInspector.panels.databases.dataGridForResult(result);
if (!dataGrid) {
var emptyMsgElement = document.createElement("div");
emptyMsgElement.className = "database-table-empty";
emptyMsgElement.textContent = WebInspector.UIString("The “%s”\ntable is empty.", this.tableName);
......@@ -64,22 +64,7 @@ WebInspector.DatabaseTableView.prototype = {
return;
}
var rowCount = table.getElementsByTagName("tr").length;
var columnCount = table.getElementsByTagName("tr").item(0).getElementsByTagName("th").length;
var tr = document.createElement("tr");
tr.className = "database-result-filler-row";
table.appendChild(tr);
if (!(rowCount % 2))
tr.addStyleClass("alternate");
for (var i = 0; i < columnCount; ++i) {
var td = document.createElement("td");
tr.appendChild(td);
}
this.element.appendChild(table);
this.element.appendChild(dataGrid.element);
},
_queryError: function(tx, error)
......
......@@ -162,79 +162,63 @@ WebInspector.DatabasesPanel.prototype = {
}
},
_tableForResult: function(result)
dataGridForResult: function(result)
{
if (!result.rows.length)
return null;
var rows = result.rows;
var length = rows.length;
var columnWidths = [];
var table = document.createElement("table");
table.className = "data-grid";
var headerRow = document.createElement("tr");
table.appendChild(headerRow);
var columns = {};
var j = 0;
for (var column in rows.item(0)) {
var th = document.createElement("th");
headerRow.appendChild(th);
var div = document.createElement("div");
div.textContent = column;
div.title = column;
th.appendChild(div);
var rows = result.rows;
for (var columnIdentifier in rows.item(0)) {
var column = {};
column.width = columnIdentifier.length;
column.title = columnIdentifier;
columnWidths[j++] = column.length;
columns[columnIdentifier] = column;
}
var nodes = [];
var length = rows.length;
for (var i = 0; i < length; ++i) {
var data = {};
var row = rows.item(i);
var tr = document.createElement("tr");
if (i % 2)
tr.className = "alternate";
table.appendChild(tr);
var j = 0;
for (var column in row) {
var td = document.createElement("td");
tr.appendChild(td);
var text = row[column];
var div = document.createElement("div");
div.textContent = text;
div.title = text;
td.appendChild(div);
if (text.length > columnWidths[j])
columnWidths[j] = text.length;
++j;
for (var columnIdentifier in row) {
var text = row[columnIdentifier];
data[columnIdentifier] = text;
if (text.length > columns[columnIdentifier].width)
columns[columnIdentifier].width = text.length;
}
var node = new WebInspector.DataGridNode(data, false);
node.selectable = false;
nodes.push(node);
}
var totalColumnWidths = 0;
length = columnWidths.length;
for (var i = 0; i < length; ++i)
totalColumnWidths += columnWidths[i];
for (var columnIdentifier in columns)
totalColumnWidths += columns[columnIdentifier].width;
// Calculate the percentage width for the columns.
var minimumPrecent = 5;
const minimumPrecent = 5;
var recoupPercent = 0;
for (var i = 0; i < length; ++i) {
columnWidths[i] = Math.round((columnWidths[i] / totalColumnWidths) * 100);
if (columnWidths[i] < minimumPrecent) {
recoupPercent += (minimumPrecent - columnWidths[i]);
columnWidths[i] = minimumPrecent;
for (var columnIdentifier in columns) {
var width = columns[columnIdentifier].width;
width = Math.round((width / totalColumnWidths) * 100);
if (width < minimumPrecent) {
recoupPercent += (minimumPrecent - width);
width = minimumPrecent;
}
columns[columnIdentifier].width = width;
}
// Enforce the minimum percentage width.
while (recoupPercent > 0) {
for (var i = 0; i < length; ++i) {
if (columnWidths[i] > minimumPrecent) {
--columnWidths[i];
for (var columnIdentifier in columns) {
if (columns[columnIdentifier].width > minimumPrecent) {
--columns[columnIdentifier].width;
--recoupPercent;
if (!recoupPercent)
break;
......@@ -242,13 +226,16 @@ WebInspector.DatabasesPanel.prototype = {
}
}
length = headerRow.childNodes.length;
for (var i = 0; i < length; ++i) {
var th = headerRow.childNodes[i];
th.style.width = columnWidths[i] + "%";
}
// Change the width property to a string suitable for a style width.
for (var columnIdentifier in columns)
columns[columnIdentifier].width += "%";
var dataGrid = new WebInspector.DataGrid(columns);
var length = nodes.length;
for (var i = 0; i < length; ++i)
dataGrid.appendChild(nodes[i]);
return table;
return dataGrid;
},
_startSidebarDragging: function(event)
......
......@@ -5,6 +5,7 @@
<file>CallStackSidebarPane.js</file>
<file>Console.js</file>
<file>Database.js</file>
<file>DataGrid.js</file>
<file>DatabaseQueryView.js</file>
<file>DatabasesPanel.js</file>
<file>DatabaseTableView.js</file>
......
......@@ -1307,9 +1307,7 @@ body.inactive .sidebar {
}
.database-view.table {
font-size: 10px;
overflow-y: auto;
overflow-x: hidden;
overflow: hidden;
}
.database-view.table .data-grid {
......@@ -1339,51 +1337,96 @@ body.inactive .sidebar {
color: rgb(66%, 33%, 33%);
}
.data-grid .database-result-filler-row {
height: auto;
}
.data-grid .database-result-filler-row.alternate td {
background-position-y: 16px;
.data-grid {
position: relative;
border: 1px solid #aaa;
}
.database-result-filler-row td {
background-image: -webkit-gradient(linear, left top, left bottom, from(white), color-stop(0.5, white), color-stop(0.5, rgb(234, 243, 255)), to(rgb(234, 243, 255)));
-webkit-background-size: auto 32px;
-webkit-background-origin: padding;
-webkit-background-clip: padding;
.data-grid:focus {
outline: none;
}
.data-grid {
border: 1px solid #aaa;
.data-grid table {
table-layout: fixed;
border-spacing: 0;
border-collapse: collapse;
width: 100%;
font-size: 10px;
font-family: Lucida Grande, sans-serif;
}
.data-grid .data-container {
position: absolute;
top: 16px;
bottom: 0;
left: 0;
right: 0;
padding-right: 14px;
overflow-x: hidden;
overflow-y: overlay;
background-image: -webkit-gradient(linear, left top, left bottom, from(white), color-stop(0.5, white), color-stop(0.5, rgb(234, 243, 255)), to(rgb(234, 243, 255)));
-webkit-background-size: 1px 32px;
}
.data-grid.inline .data-container {
position: static;
}
.data-grid th {
text-align: left;
background: url(Images/glossyHeader.png) repeat-x;
border-right: 1px solid #aaa;
background-image: url(Images/glossyHeader.png);
background-repeat: repeat-x;
border-right: 1px solid rgb(179, 179, 179);
border-bottom: 1px solid rgb(179, 179, 179);
height: 15px;
border-bottom: 1px solid #aaa;
font-weight: normal;
vertical-align: middle;
padding: 0 4px;
white-space: nowrap;
}
.data-grid tr {
height: 16px;
.data-grid th.corner {
width: 15px;
border-right: 0 none transparent;
}
.data-grid tr.filler {
display: table-row !important;
height: auto !important;
}
.data-grid tr.filler td {
height: auto !important;
padding: 0 !important;
}
.data-grid table.data {
position: absolute;
left: 0;
top: 0;
right: 16px;
bottom: 0;
height: 100%;
border-top: 0 none transparent;
background-image: -webkit-gradient(linear, left top, left bottom, from(white), color-stop(0.5, white), color-stop(0.5, rgb(234, 243, 255)), to(rgb(234, 243, 255)));
-webkit-background-size: 1px 32px;
}
.data-grid.inline table.data {
position: static;
}
.data-grid table.data tr {
display: none;
}
.data-grid tr.alternate {
background-color: rgb(236, 243, 254);
.data-grid table.data tr.revealed {
display: table-row;
}
.data-grid td {
vertical-align: top;
height: 12px;
padding: 2px 4px;
white-space: nowrap;
border-right: 1px solid #aaa;
......@@ -1396,40 +1439,86 @@ body.inactive .sidebar {
overflow: hidden;
}
.data-grid th.narrow {
width: 75px;
.data-grid th.sortable div {
position: relative;
}
.data-grid th.selected {
border-top: 1px solid rgb(156, 168, 207);
border-bottom: 1px solid rgb(107, 139, 195);
border-left: url(Images/glossySelected.png);
border-right: url(Images/glossySelected.png);
background: url(Images/glossySelected.png) repeat-x;
.data-grid th.sortable:active {
background-image: url(Images/glossyHeaderPressed.png);
}
.data-grid th.sort-ascending::before {
float: right;
display: inline-block;
margin-bottom: 2px;
margin-right: 3px;
.data-grid th.sort-ascending, .data-grid th.sort-descending {
border-right: 1px solid rgb(107, 140, 196);
border-bottom: 1px solid rgb(107, 140, 196);
background-image: url(Images/glossyHeaderSelected.png);
background-repeat: repeat-x;
}
.data-grid th.sortable.sort-ascending:active, .data-grid th.sortable.sort-descending:active {
background-image: url(Images/glossyHeaderSelectedPressed.png);
}
.data-grid th.sort-ascending div::after {
position: absolute;
top: 0;
right: 0;
width: 8px;
height: 8px;
content: url(Images/treeUpTriangleBlack.png);
}
.data-grid th.sort-descending::before {
float: right;
display: inline-block;
margin-top: 2px;
margin-right: 3px;
.data-grid th.sort-descending div::after {
position: absolute;
top: 0;
right: 0;
margin-top: 1px;
width: 8px;
height: 8px;
content: url(Images/treeDownTriangleBlack.png);
}
body.inactive .data-grid th.sort-ascending, body.inactive .data-grid th.sort-descending {
background: url(Images/glossyHeader.png) repeat-x;
background-image: url(Images/glossyHeader.png);
border-right: 1px solid rgb(179, 179, 179);
border-bottom: 1px solid rgb(179, 179, 179);
}
.data-grid tr.parent td.disclosure::before {
float: left;
content: url(Images/treeRightTriangleBlack.png);
width: 8px;
height: 8px;
margin-right: 2px;
-webkit-user-select: none;
}
.data-grid tr.expanded td.disclosure::before {
content: url(Images/treeDownTriangleBlack.png);
width: 8px;
height: 8px;
margin-top: 1px;
}
.data-grid tr.selected {
background-color: rgb(212, 212, 212);
color: inherit;
}
.data-grid:focus tr.selected {
background-color: rgb(56, 121, 217);
color: white;
}
.data-grid:focus tr.parent.selected td.disclosure::before {
content: url(Images/treeRightTriangleWhite.png);
}
.data-grid:focus tr.expanded.selected td.disclosure::before {
content: url(Images/treeDownTriangleWhite.png);
}
.data-grid tr:not(.parent) td.disclosure {
text-indent: 10px;
}
.database-view.query {
......
......@@ -41,6 +41,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="Resource.js"></script>
<script type="text/javascript" src="ResourceCategory.js"></script>
<script type="text/javascript" src="Database.js"></script>
<script type="text/javascript" src="DataGrid.js"></script>
<script type="text/javascript" src="Script.js"></script>
<script type="text/javascript" src="Breakpoint.js"></script>
<script type="text/javascript" src="SidebarPane.js"></script>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment