2 * Copyright (C) 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2009 Joseph Pecoraro
4 * Copyright (C) 2010 Google Inc. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16 * its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * @extends {WebInspector.VBox}
34 * @param {boolean} expandable
35 * @param {function()=} refreshCallback
36 * @param {function()=} selectedCallback
38 WebInspector.CookiesTable = function(expandable, refreshCallback, selectedCallback)
40 WebInspector.VBox.call(this);
42 var readOnly = expandable;
43 this._refreshCallback = refreshCallback;
46 {id: "name", title: WebInspector.UIString("Name"), sortable: true, disclosure: expandable, sort: WebInspector.DataGrid.Order.Ascending, longText: true, weight: 24},
47 {id: "value", title: WebInspector.UIString("Value"), sortable: true, longText: true, weight: 34},
48 {id: "domain", title: WebInspector.UIString("Domain"), sortable: true, weight: 7},
49 {id: "path", title: WebInspector.UIString("Path"), sortable: true, weight: 7},
50 {id: "expires", title: WebInspector.UIString("Expires / Max-Age"), sortable: true, weight: 7},
51 {id: "size", title: WebInspector.UIString("Size"), sortable: true, align: WebInspector.DataGrid.Align.Right, weight: 7},
52 {id: "httpOnly", title: WebInspector.UIString("HTTP"), sortable: true, align: WebInspector.DataGrid.Align.Center, weight: 7},
53 {id: "secure", title: WebInspector.UIString("Secure"), sortable: true, align: WebInspector.DataGrid.Align.Center, weight: 7}
57 this._dataGrid = new WebInspector.DataGrid(columns);
59 this._dataGrid = new WebInspector.DataGrid(columns, undefined, this._onDeleteCookie.bind(this), refreshCallback, this._onContextMenu.bind(this));
61 this._dataGrid.setName("cookiesTable");
62 this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged, this._rebuildTable, this);
65 this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, selectedCallback, this);
67 this._nextSelectedCookie = /** @type {?WebInspector.Cookie} */ (null);
69 this._dataGrid.show(this.element);
73 WebInspector.CookiesTable.prototype = {
75 * @param {?string} domain
77 _clearAndRefresh: function(domain)
84 * @param {!WebInspector.ContextMenu} contextMenu
85 * @param {!WebInspector.DataGridNode} node
87 _onContextMenu: function(contextMenu, node)
89 if (node === this._dataGrid.creationNode)
91 var cookie = node.cookie;
92 var domain = cookie.domain();
94 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Clear all from \"%s\"" : "Clear All from \"%s\"", domain), this._clearAndRefresh.bind(this, domain));
95 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Clear all" : "Clear All"), this._clearAndRefresh.bind(this, null));
99 * @param {!Array.<!WebInspector.Cookie>} cookies
101 setCookies: function(cookies)
103 this.setCookieFolders([{cookies: cookies}]);
107 * @param {!Array.<!{folderName: ?string, cookies: !Array.<!WebInspector.Cookie>}>} cookieFolders
109 setCookieFolders: function(cookieFolders)
111 this._data = cookieFolders;
112 this._rebuildTable();
116 * @return {?WebInspector.Cookie}
118 selectedCookie: function()
120 var node = this._dataGrid.selectedNode;
121 return node ? node.cookie : null;
125 * @param {?string=} domain
127 clear: function(domain)
129 for (var i = 0, length = this._data.length; i < length; ++i) {
130 var cookies = this._data[i].cookies;
131 for (var j = 0, cookieCount = cookies.length; j < cookieCount; ++j) {
132 if (!domain || cookies[j].domain() === domain)
138 _rebuildTable: function()
140 var selectedCookie = this._nextSelectedCookie || this.selectedCookie();
141 this._nextSelectedCookie = null;
142 this._dataGrid.rootNode().removeChildren();
143 for (var i = 0; i < this._data.length; ++i) {
144 var item = this._data[i];
145 if (item.folderName) {
146 var groupData = {name: item.folderName, value: "", domain: "", path: "", expires: "", size: this._totalSize(item.cookies), httpOnly: "", secure: ""};
147 var groupNode = new WebInspector.DataGridNode(groupData);
148 groupNode.selectable = true;
149 this._dataGrid.rootNode().appendChild(groupNode);
150 groupNode.element.classList.add("row-group");
151 this._populateNode(groupNode, item.cookies, selectedCookie);
154 this._populateNode(this._dataGrid.rootNode(), item.cookies, selectedCookie);
159 * @param {!WebInspector.DataGridNode} parentNode
160 * @param {?Array.<!WebInspector.Cookie>} cookies
161 * @param {?WebInspector.Cookie} selectedCookie
163 _populateNode: function(parentNode, cookies, selectedCookie)
165 parentNode.removeChildren();
169 this._sortCookies(cookies);
170 for (var i = 0; i < cookies.length; ++i) {
171 var cookie = cookies[i];
172 var cookieNode = this._createGridNode(cookie);
173 parentNode.appendChild(cookieNode);
174 if (selectedCookie && selectedCookie.name() === cookie.name() && selectedCookie.domain() === cookie.domain() && selectedCookie.path() === cookie.path())
179 _totalSize: function(cookies)
182 for (var i = 0; cookies && i < cookies.length; ++i)
183 totalSize += cookies[i].size();
188 * @param {!Array.<!WebInspector.Cookie>} cookies
190 _sortCookies: function(cookies)
192 var sortDirection = this._dataGrid.isSortOrderAscending() ? 1 : -1;
194 function compareTo(getter, cookie1, cookie2)
196 return sortDirection * (getter.apply(cookie1) + "").compareTo(getter.apply(cookie2) + "")
199 function numberCompare(getter, cookie1, cookie2)
201 return sortDirection * (getter.apply(cookie1) - getter.apply(cookie2));
204 function expiresCompare(cookie1, cookie2)
206 if (cookie1.session() !== cookie2.session())
207 return sortDirection * (cookie1.session() ? 1 : -1);
209 if (cookie1.session())
212 if (cookie1.maxAge() && cookie2.maxAge())
213 return sortDirection * (cookie1.maxAge() - cookie2.maxAge());
214 if (cookie1.expires() && cookie2.expires())
215 return sortDirection * (cookie1.expires() - cookie2.expires());
216 return sortDirection * (cookie1.expires() ? 1 : -1);
220 switch (this._dataGrid.sortColumnIdentifier()) {
221 case "name": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.name); break;
222 case "value": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.value); break;
223 case "domain": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.domain); break;
224 case "path": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.path); break;
225 case "expires": comparator = expiresCompare; break;
226 case "size": comparator = numberCompare.bind(null, WebInspector.Cookie.prototype.size); break;
227 case "httpOnly": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.httpOnly); break;
228 case "secure": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.secure); break;
229 default: compareTo.bind(null, WebInspector.Cookie.prototype.name);
232 cookies.sort(comparator);
236 * @param {!WebInspector.Cookie} cookie
237 * @return {!WebInspector.DataGridNode}
239 _createGridNode: function(cookie)
242 data.name = cookie.name();
243 data.value = cookie.value();
244 if (cookie.type() === WebInspector.Cookie.Type.Request) {
245 data.domain = WebInspector.UIString("N/A");
246 data.path = WebInspector.UIString("N/A");
247 data.expires = WebInspector.UIString("N/A");
249 data.domain = cookie.domain() || "";
250 data.path = cookie.path() || "";
252 data.expires = Number.secondsToString(parseInt(cookie.maxAge(), 10));
253 else if (cookie.expires())
254 data.expires = new Date(cookie.expires()).toGMTString();
256 data.expires = WebInspector.UIString("Session");
258 data.size = cookie.size();
259 const checkmark = "\u2713";
260 data.httpOnly = (cookie.httpOnly() ? checkmark : "");
261 data.secure = (cookie.secure() ? checkmark : "");
263 var node = new WebInspector.DataGridNode(data);
264 node.cookie = cookie;
265 node.selectable = true;
269 _onDeleteCookie: function(node)
271 var cookie = node.cookie;
272 var neighbour = node.traverseNextNode() || node.traversePreviousNode();
274 this._nextSelectedCookie = neighbour.cookie;
281 if (this._refreshCallback)
282 this._refreshCallback();
285 __proto__: WebInspector.VBox.prototype