0caa1b7959db485a52cca56177b768c439fd182a
[WebKit-https.git] / WebCore / inspector / front-end / CookieItemsView.js
1 /*
2  * Copyright (C) 2009 Apple Inc.  All rights reserved.
3  * Copyright (C) 2009 Joseph Pecoraro
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 WebInspector.CookieItemsView = function(cookieDomain)
31 {
32     WebInspector.View.call(this);
33
34     this.element.addStyleClass("storage-view");
35     this.element.addStyleClass("table");
36
37     this.deleteButton = new WebInspector.StatusBarButton(WebInspector.UIString("Delete"), "delete-storage-status-bar-item");
38     this.deleteButton.visible = false;
39     this.deleteButton.addEventListener("click", this._deleteButtonClicked.bind(this), false);
40
41     this.refreshButton = new WebInspector.StatusBarButton(WebInspector.UIString("Refresh"), "refresh-storage-status-bar-item");
42     this.refreshButton.addEventListener("click", this._refreshButtonClicked.bind(this), false);
43     
44     this._cookieDomain = cookieDomain;
45 }
46
47 WebInspector.CookieItemsView.prototype = {
48     get statusBarItems()
49     {
50         return [this.refreshButton.element, this.deleteButton.element];
51     },
52
53     show: function(parentElement)
54     {
55         WebInspector.View.prototype.show.call(this, parentElement);
56         this.update();
57     },
58
59     hide: function()
60     {
61         WebInspector.View.prototype.hide.call(this);
62         this.deleteButton.visible = false;
63     },
64
65     update: function()
66     {
67         this.element.removeChildren();
68
69         var self = this;
70         function callback(cookies, isAdvanced) {
71             var dataGrid = (isAdvanced ? self.dataGridForCookies(cookies) : self.simpleDataGridForCookies(cookies));
72             if (dataGrid) {
73                 self._dataGrid = dataGrid;
74                 self.element.appendChild(dataGrid.element);
75                 self._dataGrid.updateWidths();
76                 if (isAdvanced)
77                     self.deleteButton.visible = true;
78             } else {
79                 var emptyMsgElement = document.createElement("div");
80                 emptyMsgElement.className = "storage-table-empty";
81                 emptyMsgElement.textContent = WebInspector.UIString("This site has no cookies.");
82                 self.element.appendChild(emptyMsgElement);
83                 self._dataGrid = null;
84                 self.deleteButton.visible = false;
85             }
86         }
87
88         WebInspector.Cookies.getCookiesAsync(callback, this._cookieDomain);
89     },
90
91     dataGridForCookies: function(cookies)
92     {
93         if (!cookies.length)
94             return null;
95
96         for (var i = 0; i < cookies.length; ++i)
97             cookies[i].expires = new Date(cookies[i].expires);
98
99         var columns = { 0: {}, 1: {}, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 7: {} };
100         columns[0].title = WebInspector.UIString("Name");
101         columns[0].width = columns[0].title.length;
102         columns[1].title = WebInspector.UIString("Value");
103         columns[1].width = columns[1].title.length;
104         columns[2].title = WebInspector.UIString("Domain");
105         columns[2].width = columns[2].title.length;
106         columns[3].title = WebInspector.UIString("Path");
107         columns[3].width = columns[3].title.length;
108         columns[4].title = WebInspector.UIString("Expires");
109         columns[4].width = columns[4].title.length;
110         columns[5].title = WebInspector.UIString("Size");
111         columns[5].width = columns[5].title.length;
112         columns[5].aligned = "right";
113         columns[6].title = WebInspector.UIString("HTTP");
114         columns[6].width = columns[6].title.length;
115         columns[6].aligned = "centered";
116         columns[7].title = WebInspector.UIString("Secure");
117         columns[7].width = columns[7].title.length;
118         columns[7].aligned = "centered";
119
120         function updateDataAndColumn(index, value) {
121             data[index] = value;
122             if (value.length > columns[index].width)
123                 columns[index].width = value.length;
124         }
125
126         var data;
127         var nodes = [];
128         for (var i = 0; i < cookies.length; ++i) {
129             var cookie = cookies[i];
130             data = {};
131
132             updateDataAndColumn(0, cookie.name);
133             updateDataAndColumn(1, cookie.value);
134             updateDataAndColumn(2, cookie.domain);
135             updateDataAndColumn(3, cookie.path);
136             updateDataAndColumn(4, (cookie.session ? WebInspector.UIString("Session") : cookie.expires.toGMTString()));
137             updateDataAndColumn(5, Number.bytesToString(cookie.size, WebInspector.UIString));
138             updateDataAndColumn(6, (cookie.httpOnly ? "\u2713" : "")); // Checkmark
139             updateDataAndColumn(7, (cookie.secure ? "\u2713" : "")); // Checkmark
140
141             var node = new WebInspector.DataGridNode(data, false);
142             node.cookie = cookie;
143             node.selectable = true;
144             nodes.push(node);
145         }
146
147         var totalColumnWidths = 0;
148         for (var columnIdentifier in columns)
149             totalColumnWidths += columns[columnIdentifier].width;
150
151         // Enforce the Value column (the 2nd column) to be a max of 33%
152         // tweaking the raw total width because may massively outshadow the others
153         var valueColumnWidth = columns[1].width;
154         if (valueColumnWidth / totalColumnWidths > 0.33) {
155             totalColumnWidths -= valueColumnWidth;
156             totalColumnWidths *= 1.33;
157             columns[1].width = totalColumnWidths * 0.33;
158         }
159
160         // Calculate the percentage width for the columns.
161         const minimumPrecent = 6;
162         var recoupPercent = 0;
163         for (var columnIdentifier in columns) {
164             var width = columns[columnIdentifier].width;
165             width = Math.round((width / totalColumnWidths) * 100);
166             if (width < minimumPrecent) {
167                 recoupPercent += (minimumPrecent - width);
168                 width = minimumPrecent;
169             }
170             columns[columnIdentifier].width = width;
171         }
172
173         // Enforce the minimum percentage width. (need to narrow total percentage due to earlier additions)
174         while (recoupPercent > 0) {
175             for (var columnIdentifier in columns) {
176                 if (columns[columnIdentifier].width > minimumPrecent) {
177                     --columns[columnIdentifier].width;
178                     --recoupPercent;
179                     if (!recoupPercent)
180                         break;
181                 }
182             }
183         }
184
185         for (var columnIdentifier in columns)
186             columns[columnIdentifier].width += "%";
187
188         var dataGrid = new WebInspector.DataGrid(columns, null, this._deleteCookieCallback.bind(this));
189         var length = nodes.length;
190         for (var i = 0; i < length; ++i)
191             dataGrid.appendChild(nodes[i]);
192         if (length > 0)
193             nodes[0].selected = true;
194
195         return dataGrid;
196     },
197
198     simpleDataGridForCookies: function(cookies)
199     {
200         if (!cookies.length)
201             return null;
202
203         var columns = {};
204         columns[0] = {};
205         columns[1] = {};
206         columns[0].title = WebInspector.UIString("Name");
207         columns[0].width = columns[0].title.length;
208         columns[1].title = WebInspector.UIString("Value");
209         columns[1].width = columns[1].title.length;
210
211         var nodes = [];
212         for (var i = 0; i < cookies.length; ++i) {
213             var cookie = cookies[i];
214             var data = {};
215
216             var name = cookie.name;
217             data[0] = name;
218             if (name.length > columns[0].width)
219                 columns[0].width = name.length;
220
221             var value = cookie.value;
222             data[1] = value;
223             if (value.length > columns[1].width)
224                 columns[1].width = value.length;
225
226             var node = new WebInspector.DataGridNode(data, false);
227             node.selectable = true;
228             nodes.push(node);
229         }
230
231         var totalColumnWidths = columns[0].width + columns[1].width;
232         var width = Math.round((columns[0].width * 100) / totalColumnWidths);
233         const minimumPrecent = 20;
234         if (width < minimumPrecent)
235             width = minimumPrecent;
236         if (width > 100 - minimumPrecent)
237             width = 100 - minimumPrecent;
238         columns[0].width = width;
239         columns[1].width = 100 - width;
240         columns[0].width += "%";
241         columns[1].width += "%";
242
243         var dataGrid = new WebInspector.DataGrid(columns);
244         var length = nodes.length;
245         for (var i = 0; i < length; ++i)
246             dataGrid.appendChild(nodes[i]);
247         if (length > 0)
248             nodes[0].selected = true;
249
250         return dataGrid;
251     },
252     
253     resize: function()
254     {
255         if (this._dataGrid)
256             this._dataGrid.updateWidths();
257     },
258
259     _deleteButtonClicked: function(event)
260     {
261         if (!this._dataGrid || !this._dataGrid.selectedNode)
262             return;
263
264         this._deleteCookieCallback(this._dataGrid.selectedNode);
265     },
266     
267     _deleteCookieCallback: function(node)
268     {
269         var cookie = node.cookie;
270         InspectorBackend.deleteCookie(cookie.name, this._cookieDomain);
271         this.update();
272     },
273
274     _refreshButtonClicked: function(event)
275     {
276         this.update();
277     }
278 }
279
280 WebInspector.CookieItemsView.prototype.__proto__ = WebInspector.View.prototype;