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},
54 {id
: "firstPartyOnly", title
: WebInspector
.UIString("First-Party"), sortable
: true, align
: WebInspector
.DataGrid
.Align
.Center
, weight
: 7}
58 this._dataGrid
= new WebInspector
.DataGrid(columns
);
60 this._dataGrid
= new WebInspector
.DataGrid(columns
, undefined, this._onDeleteCookie
.bind(this), refreshCallback
, this._onContextMenu
.bind(this));
62 this._dataGrid
.setName("cookiesTable");
63 this._dataGrid
.addEventListener(WebInspector
.DataGrid
.Events
.SortingChanged
, this._rebuildTable
, this);
66 this._dataGrid
.addEventListener(WebInspector
.DataGrid
.Events
.SelectedNode
, selectedCallback
, this);
68 this._nextSelectedCookie
= /** @type {?WebInspector.Cookie} */ (null);
70 this._dataGrid
.show(this.element
);
74 WebInspector
.CookiesTable
.prototype = {
76 * @param {?string} domain
78 _clearAndRefresh: function(domain
)
85 * @param {!WebInspector.ContextMenu} contextMenu
86 * @param {!WebInspector.DataGridNode} node
88 _onContextMenu: function(contextMenu
, node
)
90 if (node
=== this._dataGrid
.creationNode
)
92 var cookie
= node
.cookie
;
93 var domain
= cookie
.domain();
95 contextMenu
.appendItem(WebInspector
.UIString
.capitalize("Clear ^all from \"%s\"", domain
), this._clearAndRefresh
.bind(this, domain
));
96 contextMenu
.appendItem(WebInspector
.UIString
.capitalize("Clear ^all"), this._clearAndRefresh
.bind(this, null));
100 * @param {!Array.<!WebInspector.Cookie>} cookies
102 setCookies: function(cookies
)
104 this.setCookieFolders([{cookies
: cookies
}]);
108 * @param {!Array.<!{folderName: ?string, cookies: !Array.<!WebInspector.Cookie>}>} cookieFolders
110 setCookieFolders: function(cookieFolders
)
112 this._data
= cookieFolders
;
113 this._rebuildTable();
117 * @return {?WebInspector.Cookie}
119 selectedCookie: function()
121 var node
= this._dataGrid
.selectedNode
;
122 return node
? node
.cookie
: null;
126 * @param {?string=} domain
128 clear: function(domain
)
130 for (var i
= 0, length
= this._data
.length
; i
< length
; ++i
) {
131 var cookies
= this._data
[i
].cookies
;
132 for (var j
= 0, cookieCount
= cookies
.length
; j
< cookieCount
; ++j
) {
133 if (!domain
|| cookies
[j
].domain() === domain
)
139 _rebuildTable: function()
141 var selectedCookie
= this._nextSelectedCookie
|| this.selectedCookie();
142 this._nextSelectedCookie
= null;
143 this._dataGrid
.rootNode().removeChildren();
144 for (var i
= 0; i
< this._data
.length
; ++i
) {
145 var item
= this._data
[i
];
146 if (item
.folderName
) {
147 var groupData
= {name
: item
.folderName
, value
: "", domain
: "", path
: "", expires
: "", size
: this._totalSize(item
.cookies
), httpOnly
: "", secure
: "", firstPartyOnly
: ""};
148 var groupNode
= new WebInspector
.DataGridNode(groupData
);
149 groupNode
.selectable
= true;
150 this._dataGrid
.rootNode().appendChild(groupNode
);
151 groupNode
.element().classList
.add("row-group");
152 this._populateNode(groupNode
, item
.cookies
, selectedCookie
);
155 this._populateNode(this._dataGrid
.rootNode(), item
.cookies
, selectedCookie
);
160 * @param {!WebInspector.DataGridNode} parentNode
161 * @param {?Array.<!WebInspector.Cookie>} cookies
162 * @param {?WebInspector.Cookie} selectedCookie
164 _populateNode: function(parentNode
, cookies
, selectedCookie
)
166 parentNode
.removeChildren();
170 this._sortCookies(cookies
);
171 for (var i
= 0; i
< cookies
.length
; ++i
) {
172 var cookie
= cookies
[i
];
173 var cookieNode
= this._createGridNode(cookie
);
174 parentNode
.appendChild(cookieNode
);
175 if (selectedCookie
&& selectedCookie
.name() === cookie
.name() && selectedCookie
.domain() === cookie
.domain() && selectedCookie
.path() === cookie
.path())
180 _totalSize: function(cookies
)
183 for (var i
= 0; cookies
&& i
< cookies
.length
; ++i
)
184 totalSize
+= cookies
[i
].size();
189 * @param {!Array.<!WebInspector.Cookie>} cookies
191 _sortCookies: function(cookies
)
193 var sortDirection
= this._dataGrid
.isSortOrderAscending() ? 1 : -1;
195 function compareTo(getter
, cookie1
, cookie2
)
197 return sortDirection
* (getter
.apply(cookie1
) + "").compareTo(getter
.apply(cookie2
) + "");
200 function numberCompare(getter
, cookie1
, cookie2
)
202 return sortDirection
* (getter
.apply(cookie1
) - getter
.apply(cookie2
));
205 function expiresCompare(cookie1
, cookie2
)
207 if (cookie1
.session() !== cookie2
.session())
208 return sortDirection
* (cookie1
.session() ? 1 : -1);
210 if (cookie1
.session())
213 if (cookie1
.maxAge() && cookie2
.maxAge())
214 return sortDirection
* (cookie1
.maxAge() - cookie2
.maxAge());
215 if (cookie1
.expires() && cookie2
.expires())
216 return sortDirection
* (cookie1
.expires() - cookie2
.expires());
217 return sortDirection
* (cookie1
.expires() ? 1 : -1);
221 switch (this._dataGrid
.sortColumnIdentifier()) {
222 case "name": comparator
= compareTo
.bind(null, WebInspector
.Cookie
.prototype.name
); break;
223 case "value": comparator
= compareTo
.bind(null, WebInspector
.Cookie
.prototype.value
); break;
224 case "domain": comparator
= compareTo
.bind(null, WebInspector
.Cookie
.prototype.domain
); break;
225 case "path": comparator
= compareTo
.bind(null, WebInspector
.Cookie
.prototype.path
); break;
226 case "expires": comparator
= expiresCompare
; break;
227 case "size": comparator
= numberCompare
.bind(null, WebInspector
.Cookie
.prototype.size
); break;
228 case "httpOnly": comparator
= compareTo
.bind(null, WebInspector
.Cookie
.prototype.httpOnly
); break;
229 case "secure": comparator
= compareTo
.bind(null, WebInspector
.Cookie
.prototype.secure
); break;
230 case "firstPartyOnly": comparator
= compareTo
.bind(null, WebInspector
.Cookie
.prototype.firstPartyOnly
); break;
231 default: compareTo
.bind(null, WebInspector
.Cookie
.prototype.name
);
234 cookies
.sort(comparator
);
238 * @param {!WebInspector.Cookie} cookie
239 * @return {!WebInspector.DataGridNode}
241 _createGridNode: function(cookie
)
244 data
.name
= cookie
.name();
245 data
.value
= cookie
.value();
246 if (cookie
.type() === WebInspector
.Cookie
.Type
.Request
) {
247 data
.domain
= WebInspector
.UIString("N/A");
248 data
.path
= WebInspector
.UIString("N/A");
249 data
.expires
= WebInspector
.UIString("N/A");
251 data
.domain
= cookie
.domain() || "";
252 data
.path
= cookie
.path() || "";
254 data
.expires
= Number
.secondsToString(parseInt(cookie
.maxAge(), 10));
255 else if (cookie
.expires())
256 data
.expires
= new Date(cookie
.expires()).toISOString();
258 data
.expires
= WebInspector
.UIString("Session");
260 data
.size
= cookie
.size();
261 const checkmark
= "\u2713";
262 data
.httpOnly
= (cookie
.httpOnly() ? checkmark
: "");
263 data
.secure
= (cookie
.secure() ? checkmark
: "");
264 data
.firstPartyOnly
= (cookie
.firstPartyOnly() ? checkmark
: "");
266 var node
= new WebInspector
.DataGridNode(data
);
267 node
.cookie
= cookie
;
268 node
.selectable
= true;
272 _onDeleteCookie: function(node
)
274 var cookie
= node
.cookie
;
275 var neighbour
= node
.traverseNextNode() || node
.traversePreviousNode();
277 this._nextSelectedCookie
= neighbour
.cookie
;
284 if (this._refreshCallback
)
285 this._refreshCallback();
288 __proto__
: WebInspector
.VBox
.prototype