Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(95)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/cookie_table/CookiesTable.js

Issue 2567873002: DevTools: Add ability to add and edit cookies (Closed)
Patch Set: Fix formatting. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2009 Apple Inc. All rights reserved. 2 * Copyright (C) 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2009 Joseph Pecoraro 3 * Copyright (C) 2009 Joseph Pecoraro
4 * Copyright (C) 2010 Google Inc. All rights reserved. 4 * Copyright (C) 2010 Google Inc. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 9 *
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
(...skipping 15 matching lines...) Expand all
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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 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. 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 /** 31 /**
32 * @unrestricted 32 * @unrestricted
33 */ 33 */
34 CookieTable.CookiesTable = class extends UI.VBox { 34 CookieTable.CookiesTable = class extends UI.VBox {
35 /** 35 /**
36 * @param {boolean} expandable 36 * @param {boolean} readOnly
37 * @param {function()=} refreshCallback 37 * @param {function()=} refreshCallback
38 * @param {function()=} selectedCallback 38 * @param {function()=} selectedCallback
39 * @param {string=} cookieDomain
39 */ 40 */
40 constructor(expandable, refreshCallback, selectedCallback) { 41 constructor(readOnly, refreshCallback, selectedCallback, cookieDomain) {
41 super(); 42 super();
42 43
43 var readOnly = expandable; 44 this._readOnly = readOnly;
44 this._refreshCallback = refreshCallback; 45 this._refreshCallback = refreshCallback;
46 this._cookieDomain = cookieDomain;
45 47
46 var columns = /** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([ 48 var columns = /** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([
47 { 49 {
48 id: 'name', 50 id: 'name',
49 title: Common.UIString('Name'), 51 title: Common.UIString('Name'),
50 sortable: true, 52 sortable: true,
51 disclosure: expandable, 53 disclosure: !this._readOnly,
52 sort: DataGrid.DataGrid.Order.Ascending, 54 sort: DataGrid.DataGrid.Order.Ascending,
53 longText: true, 55 longText: true,
54 weight: 24 56 weight: 24,
57 editable: !this._readOnly
55 }, 58 },
56 {id: 'value', title: Common.UIString('Value'), sortable: true, longText: t rue, weight: 34}, 59 {
57 {id: 'domain', title: Common.UIString('Domain'), sortable: true, weight: 7 }, 60 id: 'value',
58 {id: 'path', title: Common.UIString('Path'), sortable: true, weight: 7}, 61 title: Common.UIString('Value'),
59 {id: 'expires', title: Common.UIString('Expires / Max-Age'), sortable: tru e, weight: 7}, 62 sortable: true,
60 {id: 'size', title: Common.UIString('Size'), sortable: true, align: DataGr id.DataGrid.Align.Right, weight: 7}, { 63 longText: true,
64 weight: 34,
65 editable: !this._readOnly
66 },
67 {id: 'domain', title: Common.UIString('Domain'), sortable: true, weight: 7 , editable: !this._readOnly},
68 {id: 'path', title: Common.UIString('Path'), sortable: true, weight: 7, ed itable: !this._readOnly},
69 {
70 id: 'expires',
71 title: Common.UIString('Expires / Max-Age'),
72 sortable: true,
73 weight: 7,
74 editable: !this._readOnly
75 },
76 {id: 'size', title: Common.UIString('Size'), sortable: true, align: DataGr id.DataGrid.Align.Right, weight: 7},
77 {
61 id: 'httpOnly', 78 id: 'httpOnly',
62 title: Common.UIString('HTTP'), 79 title: Common.UIString('HTTP'),
63 sortable: true, 80 sortable: true,
64 align: DataGrid.DataGrid.Align.Center, 81 align: DataGrid.DataGrid.Align.Center,
65 weight: 7 82 weight: 7
66 }, 83 },
67 { 84 {
68 id: 'secure', 85 id: 'secure',
69 title: Common.UIString('Secure'), 86 title: Common.UIString('Secure'),
70 sortable: true, 87 sortable: true,
71 align: DataGrid.DataGrid.Align.Center, 88 align: DataGrid.DataGrid.Align.Center,
72 weight: 7 89 weight: 7
73 }, 90 },
74 { 91 {
75 id: 'sameSite', 92 id: 'sameSite',
76 title: Common.UIString('SameSite'), 93 title: Common.UIString('SameSite'),
77 sortable: true, 94 sortable: true,
78 align: DataGrid.DataGrid.Align.Center, 95 align: DataGrid.DataGrid.Align.Center,
79 weight: 7 96 weight: 7
80 } 97 }
81 ]); 98 ]);
82 99
83 if (readOnly) { 100 if (this._readOnly) {
84 this._dataGrid = new DataGrid.DataGrid(columns); 101 this._dataGrid = new DataGrid.DataGrid(columns);
85 } else { 102 } else {
86 this._dataGrid = new DataGrid.DataGrid(columns, undefined, this._onDeleteC ookie.bind(this), refreshCallback); 103 this._dataGrid = new DataGrid.DataGrid(columns, this._onUpdateCookie.bind( this), this._onDeleteCookie.bind(this), refreshCallback);
87 this._dataGrid.setRowContextMenuCallback(this._onRowContextMenu.bind(this) ); 104 this._dataGrid.setRowContextMenuCallback(this._onRowContextMenu.bind(this) );
88 } 105 }
89 106
90 this._dataGrid.setName('cookiesTable'); 107 this._dataGrid.setName('cookiesTable');
91 this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged, thi s._rebuildTable, this); 108 this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged, thi s._rebuildTable, this);
92 109
93 if (selectedCallback) 110 if (selectedCallback)
94 this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SelectedNode, sel ectedCallback, this); 111 this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SelectedNode, sel ectedCallback, this);
95 112
96 this._nextSelectedCookie = /** @type {?SDK.Cookie} */ (null); 113 this._nextSelectedCookie = /** @type {?SDK.Cookie} */ (null);
114 /** @type {?string} */
115 this._lastEditedColumnId = null;
97 116
98 this._dataGrid.asWidget().show(this.element); 117 this._dataGrid.asWidget().show(this.element);
99 this._data = []; 118 this._data = [];
100 } 119 }
101 120
102 /** 121 /**
103 * @param {?string} domain 122 * @param {?string} domain
104 */ 123 */
105 _clearAndRefresh(domain) { 124 _clearAndRefresh(domain) {
106 this.clear(domain); 125 this.clear(domain);
107 this._refresh(); 126 this._refresh();
108 } 127 }
109 128
110 /** 129 /**
111 * @param {!UI.ContextMenu} contextMenu 130 * @param {!UI.ContextMenu} contextMenu
112 * @param {!DataGrid.DataGridNode} node 131 * @param {!DataGrid.DataGridNode} node
113 */ 132 */
114 _onRowContextMenu(contextMenu, node) { 133 _onRowContextMenu(contextMenu, node) {
115 if (node === this._dataGrid.creationNode) 134 if (node.isCreationNode)
116 return; 135 return;
117 var domain = node.cookie.domain(); 136
137 const cookie = node.cookie;
138 const domain = cookie.domain();
118 if (domain) { 139 if (domain) {
119 contextMenu.appendItem( 140 contextMenu.appendItem(
120 Common.UIString.capitalize('Clear ^all from "%s"', domain), this._clea rAndRefresh.bind(this, domain)); 141 Common.UIString.capitalize('Clear ^all from "%s"', domain), this._clea rAndRefresh.bind(this, domain));
121 } 142 }
122 contextMenu.appendItem(Common.UIString.capitalize('Clear ^all'), this._clear AndRefresh.bind(this, null)); 143 contextMenu.appendItem(Common.UIString.capitalize('Clear ^all'), this._clear AndRefresh.bind(this, null));
123 } 144 }
124 145
125 /** 146 /**
126 * @param {!Array.<!SDK.Cookie>} cookies 147 * @param {!Array.<!SDK.Cookie>} cookies
127 */ 148 */
(...skipping 23 matching lines...) Expand all
151 clear(domain) { 172 clear(domain) {
152 for (var i = 0, length = this._data.length; i < length; ++i) { 173 for (var i = 0, length = this._data.length; i < length; ++i) {
153 var cookies = this._data[i].cookies; 174 var cookies = this._data[i].cookies;
154 for (var j = 0, cookieCount = cookies.length; j < cookieCount; ++j) { 175 for (var j = 0, cookieCount = cookies.length; j < cookieCount; ++j) {
155 if (!domain || cookies[j].domain() === domain) 176 if (!domain || cookies[j].domain() === domain)
156 cookies[j].remove(); 177 cookies[j].remove();
157 } 178 }
158 } 179 }
159 } 180 }
160 181
182 /**
183 * @override
184 */
185 willHide() {
186 this._lastEditedColumnId = null;
187 }
188
161 _rebuildTable() { 189 _rebuildTable() {
162 var selectedCookie = this._nextSelectedCookie || this.selectedCookie(); 190 var selectedCookie = this._nextSelectedCookie || this.selectedCookie();
191 var lastEditedColumnId = this._lastEditedColumnId;
163 this._nextSelectedCookie = null; 192 this._nextSelectedCookie = null;
193 this._lastEditedColumnId = null;
164 this._dataGrid.rootNode().removeChildren(); 194 this._dataGrid.rootNode().removeChildren();
165 for (var i = 0; i < this._data.length; ++i) { 195 for (var i = 0; i < this._data.length; ++i) {
166 var item = this._data[i]; 196 var item = this._data[i];
167 if (item.folderName) { 197 if (item.folderName) {
168 var groupData = { 198 var groupData = {
169 name: item.folderName, 199 name: item.folderName,
170 value: '', 200 value: '',
171 domain: '', 201 domain: '',
172 path: '', 202 path: '',
173 expires: '', 203 expires: '',
174 size: this._totalSize(item.cookies), 204 size: this._totalSize(item.cookies),
175 httpOnly: '', 205 httpOnly: '',
176 secure: '', 206 secure: '',
177 sameSite: '' 207 sameSite: ''
178 }; 208 };
179 var groupNode = new DataGrid.DataGridNode(groupData); 209 var groupNode = new DataGrid.DataGridNode(groupData);
180 groupNode.selectable = true; 210 groupNode.selectable = true;
181 this._dataGrid.rootNode().appendChild(groupNode); 211 this._dataGrid.rootNode().appendChild(groupNode);
182 groupNode.element().classList.add('row-group'); 212 groupNode.element().classList.add('row-group');
183 this._populateNode(groupNode, item.cookies, selectedCookie); 213 this._populateNode(groupNode, item.cookies, selectedCookie, lastEditedCo lumnId);
184 groupNode.expand(); 214 groupNode.expand();
185 } else { 215 } else {
186 this._populateNode(this._dataGrid.rootNode(), item.cookies, selectedCook ie); 216 this._populateNode(this._dataGrid.rootNode(), item.cookies, selectedCook ie, lastEditedColumnId);
187 } 217 }
188 } 218 }
219 if (selectedCookie && lastEditedColumnId && !this._dataGrid.selectedNode)
220 this._addInactiveNode(this._dataGrid.rootNode(), selectedCookie, lastEdi tedColumnId);
dgozman 2017/01/20 01:54:51 style: 2 spaces indent
kdzwinel 2017/01/21 02:12:20 thanks! It looks like linter isn't configured to r
221 if (!this._readOnly)
222 this._dataGrid.addCreationNode(false);
189 } 223 }
190 224
191 /** 225 /**
192 * @param {!DataGrid.DataGridNode} parentNode 226 * @param {!DataGrid.DataGridNode} parentNode
193 * @param {?Array.<!SDK.Cookie>} cookies 227 * @param {?Array.<!SDK.Cookie>} cookies
194 * @param {?SDK.Cookie} selectedCookie 228 * @param {?SDK.Cookie} selectedCookie
229 * @param {?string} lastEditedColumnId
195 */ 230 */
196 _populateNode(parentNode, cookies, selectedCookie) { 231 _populateNode(parentNode, cookies, selectedCookie, lastEditedColumnId) {
197 parentNode.removeChildren(); 232 parentNode.removeChildren();
198 if (!cookies) 233 if (!cookies)
199 return; 234 return;
200 235
201 this._sortCookies(cookies); 236 this._sortCookies(cookies);
202 for (var i = 0; i < cookies.length; ++i) { 237 for (var i = 0; i < cookies.length; ++i) {
203 var cookie = cookies[i]; 238 var cookie = cookies[i];
204 var cookieNode = this._createGridNode(cookie); 239 var cookieNode = this._createGridNode(cookie);
205 parentNode.appendChild(cookieNode); 240 parentNode.appendChild(cookieNode);
206 if (selectedCookie && selectedCookie.name() === cookie.name() && selectedC ookie.domain() === cookie.domain() && 241 if (selectedCookie && selectedCookie.name() === cookie.name() && selectedC ookie.domain() === cookie.domain() &&
207 selectedCookie.path() === cookie.path()) 242 selectedCookie.path() === cookie.path()) {
208 cookieNode.select(); 243 cookieNode.select();
244 if (lastEditedColumnId !== null)
245 this._dataGrid.startEditingNextEditableColumnOfDataGridNode(cookieNode , lastEditedColumnId);
246 }
209 } 247 }
210 } 248 }
211 249
250 /**
251 * @param {!DataGrid.DataGridNode} parentNode
252 * @param {!SDK.Cookie} cookie
253 * @param {?string} editedColumnId
254 */
255 _addInactiveNode(parentNode, cookie, editedColumnId) {
256 const cookieNode = this._createGridNode(cookie);
257 parentNode.appendChild(cookieNode);
258 cookieNode.select();
259 cookieNode.setInactive(true);
260 if (editedColumnId !== null)
261 this._dataGrid.startEditingNextEditableColumnOfDataGridNode(cookieNode, ed itedColumnId);
262 }
263
212 _totalSize(cookies) { 264 _totalSize(cookies) {
213 var totalSize = 0; 265 var totalSize = 0;
214 for (var i = 0; cookies && i < cookies.length; ++i) 266 for (var i = 0; cookies && i < cookies.length; ++i)
215 totalSize += cookies[i].size(); 267 totalSize += cookies[i].size();
216 return totalSize; 268 return totalSize;
217 } 269 }
218 270
219 /** 271 /**
220 * @param {!Array.<!SDK.Cookie>} cookies 272 * @param {!Array.<!SDK.Cookie>} cookies
221 */ 273 */
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 data.path = Common.UIString('N/A'); 342 data.path = Common.UIString('N/A');
291 data.expires = Common.UIString('N/A'); 343 data.expires = Common.UIString('N/A');
292 } else { 344 } else {
293 data.domain = cookie.domain() || ''; 345 data.domain = cookie.domain() || '';
294 data.path = cookie.path() || ''; 346 data.path = cookie.path() || '';
295 if (cookie.maxAge()) 347 if (cookie.maxAge())
296 data.expires = Number.secondsToString(parseInt(cookie.maxAge(), 10)); 348 data.expires = Number.secondsToString(parseInt(cookie.maxAge(), 10));
297 else if (cookie.expires()) 349 else if (cookie.expires())
298 data.expires = new Date(cookie.expires()).toISOString(); 350 data.expires = new Date(cookie.expires()).toISOString();
299 else 351 else
300 data.expires = Common.UIString('Session'); 352 data.expires = CookieTable.CookiesTable._expiresSessionValue;
301 } 353 }
302 data.size = cookie.size(); 354 data.size = cookie.size();
303 const checkmark = '\u2713'; 355 const checkmark = '\u2713';
304 data.httpOnly = (cookie.httpOnly() ? checkmark : ''); 356 data.httpOnly = (cookie.httpOnly() ? checkmark : '');
305 data.secure = (cookie.secure() ? checkmark : ''); 357 data.secure = (cookie.secure() ? checkmark : '');
306 data.sameSite = cookie.sameSite() || ''; 358 data.sameSite = cookie.sameSite() || '';
307 359
308 var node = new DataGrid.DataGridNode(data); 360 var node = new DataGrid.DataGridNode(data);
309 node.cookie = cookie; 361 node.cookie = cookie;
310 node.selectable = true; 362 node.selectable = true;
311 return node; 363 return node;
312 } 364 }
313 365
314 _onDeleteCookie(node) { 366 _onDeleteCookie(node) {
315 var cookie = node.cookie; 367 var cookie = node.cookie;
316 var neighbour = node.traverseNextNode() || node.traversePreviousNode(); 368 var neighbour = node.traverseNextNode() || node.traversePreviousNode();
317 if (neighbour) 369 if (neighbour)
318 this._nextSelectedCookie = neighbour.cookie; 370 this._nextSelectedCookie = neighbour.cookie;
319 cookie.remove(); 371 cookie.remove();
320 this._refresh(); 372 this._refresh();
321 } 373 }
322 374
375 /**
376 * @param {!DataGrid.DataGridNode} editingNode
377 * @param {string} columnIdentifier
378 * @param {string} oldText
379 * @param {string} newText
380 */
381 _onUpdateCookie(editingNode, columnIdentifier, oldText, newText) {
382 this._lastEditedColumnId = columnIdentifier;
383 this._setDefaults(editingNode);
384 if (this._isValidCookieData(editingNode.data))
385 this._saveNode(editingNode);
386 else
387 editingNode.setDirty(true);
388 }
389
390 /**
391 * @param {!DataGrid.DataGridNode} node
392 */
393 _setDefaults(node) {
394 if (node.data.name === null)
395 node.data.name = '';
396 if (node.data.value === null)
397 node.data.value = '';
398 if (node.data.domain === null)
399 node.data.domain = this._cookieDomain;
dgozman 2017/01/20 01:54:51 You should strip down the port number. Try adding
kdzwinel 2017/01/21 02:12:20 I haven't realized that `"...".asParsedURL().domai
400 if (node.data.path === null)
401 node.data.path = '/';
402 if (node.data.expires === null)
403 node.data.expires = CookieTable.CookiesTable._expiresSessionValue;
404 }
405
406 /**
407 * @param {!DataGrid.DataGridNode} node
408 */
409 _saveNode(node) {
410 var oldCookie = node.cookie;
411 var newCookie = this._createCookieFromData(node.data);
412 if (oldCookie && (newCookie.name() !== oldCookie.name() || newCookie.url() ! == oldCookie.url()))
413 oldCookie.remove();
414 node.cookie = newCookie;
415 newCookie.save((error, success) => {
416 if (success)
417 this._refresh();
418 else
419 node.setDirty(true);
420 });
421 this._nextSelectedCookie = newCookie;
422 }
423
424 /**
425 * @param {!Object.<string, *>} data
426 * @returns {SDK.Cookie}
427 */
428 _createCookieFromData(data) {
429 var target = SDK.targetManager.targets(SDK.Target.Capability.Network)[0];
430 var cookie = new SDK.Cookie(target, data.name, data.value, null);
431 cookie.addAttribute('domain', data.domain);
432 cookie.addAttribute('path', data.path);
433 if (data.expires && data.expires !== CookieTable.CookiesTable._expiresSessio nValue)
434 cookie.addAttribute('expires', (new Date(data.expires)).toUTCString());
435 if (data.httpOnly)
436 cookie.addAttribute('httpOnly');
437 if (data.secure)
438 cookie.addAttribute('secure');
439 if (data.sameSite)
440 cookie.addAttribute('sameSite', data.sameSite);
441 cookie.setSize(data.name.length + data.value.length);
442 return cookie;
443 }
444
445 /**
446 * @param {!Object.<string, *>} data
447 * @returns {boolean}
448 */
449 _isValidCookieData(data) {
450 return (data.name || data.value) && this._isValidDomain(data.domain) && this ._isValidPath(data.path) && this._isValidDate(data.expires);
451 }
452
453 /**
454 * @param {string} domain
455 * @returns {boolean}
456 */
457 _isValidDomain(domain) {
458 if (!domain)
459 return true;
460 var parsedURL = ('http://' + domain).asParsedURL();
461 return !!parsedURL && parsedURL.domain() === domain;
462 }
463
464 /**
465 * @param {string} path
466 * @returns {boolean}
467 */
468 _isValidPath(path) {
469 var parsedURL = ('http://example.com' + path).asParsedURL();
470 return !!parsedURL && parsedURL.path === path;
471 }
472
473 /**
474 * @param {string} date
475 * @returns {boolean}
476 */
477 _isValidDate(date) {
478 return date === '' || date === CookieTable.CookiesTable._expiresSessionValue || !isNaN(Date.parse(date));
479 }
480
323 _refresh() { 481 _refresh() {
324 if (this._refreshCallback) 482 if (this._refreshCallback)
325 this._refreshCallback(); 483 this._refreshCallback();
326 } 484 }
327 }; 485 };
486
487 /** @const */
488 CookieTable.CookiesTable._expiresSessionValue = Common.UIString('Session');
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698