Web Inspector: Reduce synchronous view layouts
[WebKit-https.git] / Source / WebInspectorUI / UserInterface / Views / DatabaseTableContentView.js
1 /*
2  * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 WebInspector.DatabaseTableContentView = class DatabaseTableContentView extends WebInspector.ContentView
27 {
28     constructor(representedObject)
29     {
30         super(representedObject);
31
32         this.element.classList.add("database-table");
33
34         this._refreshButtonNavigationItem = new WebInspector.ButtonNavigationItem("database-table-refresh", WebInspector.UIString("Refresh"), "Images/ReloadFull.svg", 13, 13);
35         this._refreshButtonNavigationItem.addEventListener(WebInspector.ButtonNavigationItem.Event.Clicked, this._refreshButtonClicked, this);
36         this._messageTextViewElement = null;
37
38         this.update();
39     }
40
41     // Public
42
43     get navigationItems()
44     {
45         return [this._refreshButtonNavigationItem];
46     }
47
48     update()
49     {
50         this.representedObject.database.executeSQL("SELECT * FROM \"" + this._escapeTableName(this.representedObject.name) + "\"", this._queryFinished.bind(this), this._queryError.bind(this));
51     }
52
53     saveToCookie(cookie)
54     {
55         cookie.type = WebInspector.ContentViewCookieType.DatabaseTable;
56         cookie.host = this.representedObject.host;
57         cookie.name = this.representedObject.name;
58         cookie.database = this.representedObject.database.name;
59     }
60
61     get scrollableElements()
62     {
63         if (!this._dataGrid)
64             return [];
65         return [this._dataGrid.scrollContainer];
66     }
67
68     // Private
69
70     _escapeTableName(name)
71     {
72         return name.replace(/\"/g, "\"\"");
73     }
74
75     _queryFinished(columnNames, values)
76     {
77         // It would be nice to do better than creating a new data grid each time the table is updated, but the table updating
78         // doesn't happen very frequently. Additionally, using DataGrid's createSortableDataGrid makes our code much cleaner and it knows
79         // how to sort arbitrary columns.
80         if (this._dataGrid) {
81             this.removeSubview(this._dataGrid);
82             this._dataGrid = null;
83         }
84
85         if (this._messageTextViewElement)
86             this._messageTextViewElement.remove();
87
88         if (columnNames.length) {
89             this._dataGrid = WebInspector.DataGrid.createSortableDataGrid(columnNames, values);
90
91             this.addSubview(this._dataGrid);
92             this._dataGrid.updateLayout();
93             return;
94         }
95
96         // We were returned a table with no columns. This can happen when a table has
97         // no data, the SELECT query only returns column names when there is data.
98         this._messageTextViewElement = WebInspector.createMessageTextView(WebInspector.UIString("The ā€œ%sā€\ntable is empty.").format(this.representedObject.name), false);
99         this.element.appendChild(this._messageTextViewElement);
100     }
101
102     _queryError(error)
103     {
104         if (this._dataGrid) {
105             this.removeSubview(this._dataGrid);
106             this._dataGrid = null;
107         }
108
109         if (this._messageTextViewElement)
110             this._messageTextViewElement.remove();
111
112         this._messageTextViewElement = WebInspector.createMessageTextView(WebInspector.UIString("An error occured trying to\nread the ā€œ%sā€ table.").format(this.representedObject.name), true);
113         this.element.appendChild(this._messageTextViewElement);
114     }
115
116     _refreshButtonClicked()
117     {
118         this.update();
119     }
120 };