OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2009 Apple Inc. All rights reserved. | |
3 * Copyright (C) 2009 Joseph Pecoraro | |
4 * Copyright (C) 2010 Google Inc. All rights reserved. | |
5 * | |
6 * Redistribution and use in source and binary forms, with or without | |
7 * modification, are permitted provided that the following conditions | |
8 * are met: | |
9 * | |
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. | |
18 * | |
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. | |
29 */ | |
30 | |
31 /** | |
32 * @unrestricted | |
33 */ | |
34 Components.CookiesTable = class extends UI.VBox { | |
35 /** | |
36 * @param {boolean} expandable | |
37 * @param {function()=} refreshCallback | |
38 * @param {function()=} selectedCallback | |
39 */ | |
40 constructor(expandable, refreshCallback, selectedCallback) { | |
41 super(); | |
42 | |
43 var readOnly = expandable; | |
44 this._refreshCallback = refreshCallback; | |
45 | |
46 var columns = /** @type {!Array<!UI.DataGrid.ColumnDescriptor>} */ ([ | |
47 { | |
48 id: 'name', | |
49 title: Common.UIString('Name'), | |
50 sortable: true, | |
51 disclosure: expandable, | |
52 sort: UI.DataGrid.Order.Ascending, | |
53 longText: true, | |
54 weight: 24 | |
55 }, | |
56 {id: 'value', title: Common.UIString('Value'), sortable: true, longText: t
rue, weight: 34}, | |
57 {id: 'domain', title: Common.UIString('Domain'), sortable: true, weight: 7
}, | |
58 {id: 'path', title: Common.UIString('Path'), sortable: true, weight: 7}, | |
59 {id: 'expires', title: Common.UIString('Expires / Max-Age'), sortable: tru
e, weight: 7}, | |
60 {id: 'size', title: Common.UIString('Size'), sortable: true, align: UI.Dat
aGrid.Align.Right, weight: 7}, | |
61 {id: 'httpOnly', title: Common.UIString('HTTP'), sortable: true, align: UI
.DataGrid.Align.Center, weight: 7}, | |
62 {id: 'secure', title: Common.UIString('Secure'), sortable: true, align: UI
.DataGrid.Align.Center, weight: 7}, { | |
63 id: 'sameSite', | |
64 title: Common.UIString('SameSite'), | |
65 sortable: true, | |
66 align: UI.DataGrid.Align.Center, | |
67 weight: 7 | |
68 } | |
69 ]); | |
70 | |
71 if (readOnly) { | |
72 this._dataGrid = new UI.DataGrid(columns); | |
73 } else { | |
74 this._dataGrid = new UI.DataGrid(columns, undefined, this._onDeleteCookie.
bind(this), refreshCallback); | |
75 this._dataGrid.setRowContextMenuCallback(this._onRowContextMenu.bind(this)
); | |
76 } | |
77 | |
78 this._dataGrid.setName('cookiesTable'); | |
79 this._dataGrid.addEventListener(UI.DataGrid.Events.SortingChanged, this._reb
uildTable, this); | |
80 | |
81 if (selectedCallback) | |
82 this._dataGrid.addEventListener(UI.DataGrid.Events.SelectedNode, selectedC
allback, this); | |
83 | |
84 this._nextSelectedCookie = /** @type {?SDK.Cookie} */ (null); | |
85 | |
86 this._dataGrid.asWidget().show(this.element); | |
87 this._data = []; | |
88 } | |
89 | |
90 /** | |
91 * @param {?string} domain | |
92 */ | |
93 _clearAndRefresh(domain) { | |
94 this.clear(domain); | |
95 this._refresh(); | |
96 } | |
97 | |
98 /** | |
99 * @param {!UI.ContextMenu} contextMenu | |
100 * @param {!UI.DataGridNode} node | |
101 */ | |
102 _onRowContextMenu(contextMenu, node) { | |
103 if (node === this._dataGrid.creationNode) | |
104 return; | |
105 var domain = node.cookie.domain(); | |
106 if (domain) { | |
107 contextMenu.appendItem( | |
108 Common.UIString.capitalize('Clear ^all from "%s"', domain), this._clea
rAndRefresh.bind(this, domain)); | |
109 } | |
110 contextMenu.appendItem(Common.UIString.capitalize('Clear ^all'), this._clear
AndRefresh.bind(this, null)); | |
111 } | |
112 | |
113 /** | |
114 * @param {!Array.<!SDK.Cookie>} cookies | |
115 */ | |
116 setCookies(cookies) { | |
117 this.setCookieFolders([{cookies: cookies}]); | |
118 } | |
119 | |
120 /** | |
121 * @param {!Array.<!{folderName: ?string, cookies: !Array.<!SDK.Cookie>}>} coo
kieFolders | |
122 */ | |
123 setCookieFolders(cookieFolders) { | |
124 this._data = cookieFolders; | |
125 this._rebuildTable(); | |
126 } | |
127 | |
128 /** | |
129 * @return {?SDK.Cookie} | |
130 */ | |
131 selectedCookie() { | |
132 var node = this._dataGrid.selectedNode; | |
133 return node ? node.cookie : null; | |
134 } | |
135 | |
136 /** | |
137 * @param {?string=} domain | |
138 */ | |
139 clear(domain) { | |
140 for (var i = 0, length = this._data.length; i < length; ++i) { | |
141 var cookies = this._data[i].cookies; | |
142 for (var j = 0, cookieCount = cookies.length; j < cookieCount; ++j) { | |
143 if (!domain || cookies[j].domain() === domain) | |
144 cookies[j].remove(); | |
145 } | |
146 } | |
147 } | |
148 | |
149 _rebuildTable() { | |
150 var selectedCookie = this._nextSelectedCookie || this.selectedCookie(); | |
151 this._nextSelectedCookie = null; | |
152 this._dataGrid.rootNode().removeChildren(); | |
153 for (var i = 0; i < this._data.length; ++i) { | |
154 var item = this._data[i]; | |
155 if (item.folderName) { | |
156 var groupData = { | |
157 name: item.folderName, | |
158 value: '', | |
159 domain: '', | |
160 path: '', | |
161 expires: '', | |
162 size: this._totalSize(item.cookies), | |
163 httpOnly: '', | |
164 secure: '', | |
165 sameSite: '' | |
166 }; | |
167 var groupNode = new UI.DataGridNode(groupData); | |
168 groupNode.selectable = true; | |
169 this._dataGrid.rootNode().appendChild(groupNode); | |
170 groupNode.element().classList.add('row-group'); | |
171 this._populateNode(groupNode, item.cookies, selectedCookie); | |
172 groupNode.expand(); | |
173 } else { | |
174 this._populateNode(this._dataGrid.rootNode(), item.cookies, selectedCook
ie); | |
175 } | |
176 } | |
177 } | |
178 | |
179 /** | |
180 * @param {!UI.DataGridNode} parentNode | |
181 * @param {?Array.<!SDK.Cookie>} cookies | |
182 * @param {?SDK.Cookie} selectedCookie | |
183 */ | |
184 _populateNode(parentNode, cookies, selectedCookie) { | |
185 parentNode.removeChildren(); | |
186 if (!cookies) | |
187 return; | |
188 | |
189 this._sortCookies(cookies); | |
190 for (var i = 0; i < cookies.length; ++i) { | |
191 var cookie = cookies[i]; | |
192 var cookieNode = this._createGridNode(cookie); | |
193 parentNode.appendChild(cookieNode); | |
194 if (selectedCookie && selectedCookie.name() === cookie.name() && selectedC
ookie.domain() === cookie.domain() && | |
195 selectedCookie.path() === cookie.path()) | |
196 cookieNode.select(); | |
197 } | |
198 } | |
199 | |
200 _totalSize(cookies) { | |
201 var totalSize = 0; | |
202 for (var i = 0; cookies && i < cookies.length; ++i) | |
203 totalSize += cookies[i].size(); | |
204 return totalSize; | |
205 } | |
206 | |
207 /** | |
208 * @param {!Array.<!SDK.Cookie>} cookies | |
209 */ | |
210 _sortCookies(cookies) { | |
211 var sortDirection = this._dataGrid.isSortOrderAscending() ? 1 : -1; | |
212 | |
213 /** | |
214 * @param {!SDK.Cookie} cookie | |
215 * @param {string} property | |
216 * @return {string} | |
217 */ | |
218 function getValue(cookie, property) { | |
219 return typeof cookie[property] === 'function' ? String(cookie[property]())
: String(cookie.name()); | |
220 } | |
221 | |
222 /** | |
223 * @param {string} property | |
224 * @param {!SDK.Cookie} cookie1 | |
225 * @param {!SDK.Cookie} cookie2 | |
226 */ | |
227 function compareTo(property, cookie1, cookie2) { | |
228 return sortDirection * getValue(cookie1, property).compareTo(getValue(cook
ie2, property)); | |
229 } | |
230 | |
231 /** | |
232 * @param {!SDK.Cookie} cookie1 | |
233 * @param {!SDK.Cookie} cookie2 | |
234 */ | |
235 function numberCompare(cookie1, cookie2) { | |
236 return sortDirection * (cookie1.size() - cookie2.size()); | |
237 } | |
238 | |
239 /** | |
240 * @param {!SDK.Cookie} cookie1 | |
241 * @param {!SDK.Cookie} cookie2 | |
242 */ | |
243 function expiresCompare(cookie1, cookie2) { | |
244 if (cookie1.session() !== cookie2.session()) | |
245 return sortDirection * (cookie1.session() ? 1 : -1); | |
246 | |
247 if (cookie1.session()) | |
248 return 0; | |
249 | |
250 if (cookie1.maxAge() && cookie2.maxAge()) | |
251 return sortDirection * (cookie1.maxAge() - cookie2.maxAge()); | |
252 if (cookie1.expires() && cookie2.expires()) | |
253 return sortDirection * (cookie1.expires() - cookie2.expires()); | |
254 return sortDirection * (cookie1.expires() ? 1 : -1); | |
255 } | |
256 | |
257 var comparator; | |
258 var columnId = this._dataGrid.sortColumnId() || 'name'; | |
259 if (columnId === 'expires') | |
260 comparator = expiresCompare; | |
261 else if (columnId === 'size') | |
262 comparator = numberCompare; | |
263 else | |
264 comparator = compareTo.bind(null, columnId); | |
265 cookies.sort(comparator); | |
266 } | |
267 | |
268 /** | |
269 * @param {!SDK.Cookie} cookie | |
270 * @return {!UI.DataGridNode} | |
271 */ | |
272 _createGridNode(cookie) { | |
273 var data = {}; | |
274 data.name = cookie.name(); | |
275 data.value = cookie.value(); | |
276 if (cookie.type() === SDK.Cookie.Type.Request) { | |
277 data.domain = Common.UIString('N/A'); | |
278 data.path = Common.UIString('N/A'); | |
279 data.expires = Common.UIString('N/A'); | |
280 } else { | |
281 data.domain = cookie.domain() || ''; | |
282 data.path = cookie.path() || ''; | |
283 if (cookie.maxAge()) | |
284 data.expires = Number.secondsToString(parseInt(cookie.maxAge(), 10)); | |
285 else if (cookie.expires()) | |
286 data.expires = new Date(cookie.expires()).toISOString(); | |
287 else | |
288 data.expires = Common.UIString('Session'); | |
289 } | |
290 data.size = cookie.size(); | |
291 const checkmark = '\u2713'; | |
292 data.httpOnly = (cookie.httpOnly() ? checkmark : ''); | |
293 data.secure = (cookie.secure() ? checkmark : ''); | |
294 data.sameSite = cookie.sameSite() || ''; | |
295 | |
296 var node = new UI.DataGridNode(data); | |
297 node.cookie = cookie; | |
298 node.selectable = true; | |
299 return node; | |
300 } | |
301 | |
302 _onDeleteCookie(node) { | |
303 var cookie = node.cookie; | |
304 var neighbour = node.traverseNextNode() || node.traversePreviousNode(); | |
305 if (neighbour) | |
306 this._nextSelectedCookie = neighbour.cookie; | |
307 cookie.remove(); | |
308 this._refresh(); | |
309 } | |
310 | |
311 _refresh() { | |
312 if (this._refreshCallback) | |
313 this._refreshCallback(); | |
314 } | |
315 }; | |
OLD | NEW |