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

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

Issue 2567873002: DevTools: Add ability to add and edit cookies (Closed)
Patch Set: Code review fixes - part 5. Created 4 years 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 Components.CookiesTable = class extends UI.VBox { 34 Components.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<!UI.DataGrid.ColumnDescriptor>} */ ([ 48 var columns = /** @type {!Array<!UI.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: UI.DataGrid.Order.Ascending, 54 sort: UI.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 {id: 'value', title: Common.UIString('Value'), sortable: true, longText: t rue, weight: 34, editable: !this._readOnly},
57 {id: 'domain', title: Common.UIString('Domain'), sortable: true, weight: 7 }, 60 {id: 'domain', title: Common.UIString('Domain'), sortable: true, weight: 7 , editable: !this._readOnly},
58 {id: 'path', title: Common.UIString('Path'), sortable: true, weight: 7}, 61 {id: 'path', title: Common.UIString('Path'), sortable: true, weight: 7, ed itable: !this._readOnly},
59 {id: 'expires', title: Common.UIString('Expires / Max-Age'), sortable: tru e, weight: 7}, 62 {id: 'expires', title: Common.UIString('Expires / Max-Age'), sortable: tru e, weight: 7, editable: !this._readOnly},
60 {id: 'size', title: Common.UIString('Size'), sortable: true, align: UI.Dat aGrid.Align.Right, weight: 7}, 63 {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}, 64 {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}, { 65 {id: 'secure', title: Common.UIString('Secure'), sortable: true, align: UI .DataGrid.Align.Center, weight: 7}, {
63 id: 'sameSite', 66 id: 'sameSite',
64 title: Common.UIString('SameSite'), 67 title: Common.UIString('SameSite'),
65 sortable: true, 68 sortable: true,
66 align: UI.DataGrid.Align.Center, 69 align: UI.DataGrid.Align.Center,
67 weight: 7 70 weight: 7
68 } 71 }
69 ]); 72 ]);
70 73
71 if (readOnly) { 74 if (this._readOnly) {
72 this._dataGrid = new UI.DataGrid(columns); 75 this._dataGrid = new UI.DataGrid(columns);
73 } else { 76 } else {
74 this._dataGrid = new UI.DataGrid(columns, undefined, this._onDeleteCookie. bind(this), refreshCallback); 77 this._dataGrid = new UI.DataGrid(columns, this._onUpdateCookie.bind(this), this._onDeleteCookie.bind(this), refreshCallback);
75 this._dataGrid.setRowContextMenuCallback(this._onRowContextMenu.bind(this) ); 78 this._dataGrid.setRowContextMenuCallback(this._onRowContextMenu.bind(this) );
76 } 79 }
77 80
78 this._dataGrid.setName('cookiesTable'); 81 this._dataGrid.setName('cookiesTable');
79 this._dataGrid.addEventListener(UI.DataGrid.Events.SortingChanged, this._reb uildTable, this); 82 this._dataGrid.addEventListener(UI.DataGrid.Events.SortingChanged, this._reb uildTable, this);
80 83
81 if (selectedCallback) 84 if (selectedCallback)
82 this._dataGrid.addEventListener(UI.DataGrid.Events.SelectedNode, selectedC allback, this); 85 this._dataGrid.addEventListener(UI.DataGrid.Events.SelectedNode, selectedC allback, this);
83 86
84 this._nextSelectedCookie = /** @type {?SDK.Cookie} */ (null); 87 this._nextSelectedCookie = /** @type {?SDK.Cookie} */ (null);
88 /** @type {?string} */
89 this._lastEditedColumnId = null;
85 90
86 this._dataGrid.asWidget().show(this.element); 91 this._dataGrid.asWidget().show(this.element);
87 this._data = []; 92 this._data = [];
88 } 93 }
89 94
90 /** 95 /**
91 * @param {?string} domain 96 * @param {?string} domain
92 */ 97 */
93 _clearAndRefresh(domain) { 98 _clearAndRefresh(domain) {
94 this.clear(domain); 99 this.clear(domain);
95 this._refresh(); 100 this._refresh();
96 } 101 }
97 102
98 /** 103 /**
99 * @param {!UI.ContextMenu} contextMenu 104 * @param {!UI.ContextMenu} contextMenu
100 * @param {!UI.DataGridNode} node 105 * @param {!UI.DataGridNode} node
101 */ 106 */
102 _onRowContextMenu(contextMenu, node) { 107 _onRowContextMenu(contextMenu, node) {
103 if (node === this._dataGrid.creationNode) 108 if (node.isCreationNode)
104 return; 109 return;
105 var domain = node.cookie.domain(); 110
111 const cookie = node.cookie;
112 const checkmark = '\u2713';
113 contextMenu.appendCheckboxItem(
114 Common.UIString('Secure flag'),
115 this._setCookieFlag.bind(this, node, 'secure', cookie.secure() ? '' : chec kmark),
116 cookie.secure(),
117 false
118 );
119 contextMenu.appendCheckboxItem(
120 Common.UIString('HttpOnly flag'),
121 this._setCookieFlag.bind(this, node, 'httpOnly', cookie.httpOnly() ? '' : checkmark),
122 cookie.httpOnly(),
123 false
124 );
125
126 var sameSiteSubmenu = contextMenu.appendSubMenuItem(Common.UIString('SameSit e flag'));
127 sameSiteSubmenu.appendCheckboxItem(
128 Common.UIString('No Restriction'),
129 this._setCookieFlag.bind(this, node, 'sameSite', ''),
130 !cookie.sameSite(),
131 false
132 );
133 sameSiteSubmenu.appendCheckboxItem(
134 Protocol.Network.CookieSameSite.Lax,
135 this._setCookieFlag.bind(this, node, 'sameSite', Protocol.Network.CookieSa meSite.Lax),
136 cookie.sameSite() === Protocol.Network.CookieSameSite.Lax,
137 false
138 );
139 sameSiteSubmenu.appendCheckboxItem(
140 Protocol.Network.CookieSameSite.Strict,
141 this._setCookieFlag.bind(this, node, 'sameSite', Protocol.Network.CookieSa meSite.Strict),
142 cookie.sameSite() === Protocol.Network.CookieSameSite.Strict,
143 false
144 );
145 contextMenu.appendSeparator();
146
147 var domain = cookie.domain();
106 if (domain) { 148 if (domain) {
107 contextMenu.appendItem( 149 contextMenu.appendItem(
108 Common.UIString.capitalize('Clear ^all from "%s"', domain), this._clea rAndRefresh.bind(this, domain)); 150 Common.UIString.capitalize('Clear ^all from "%s"', domain), this._clea rAndRefresh.bind(this, domain));
109 } 151 }
110 contextMenu.appendItem(Common.UIString.capitalize('Clear ^all'), this._clear AndRefresh.bind(this, null)); 152 contextMenu.appendItem(Common.UIString.capitalize('Clear ^all'), this._clear AndRefresh.bind(this, null));
111 } 153 }
112 154
113 /** 155 /**
156 * @param {!UI.DataGridNode} node
157 * @param {string} flag
158 * @param {string} value
159 */
160 _setCookieFlag(node, flag, value) {
161 node.data[flag] = value;
162 node.refresh();
163 this._saveNode(node);
164 }
165
166 /**
114 * @param {!Array.<!SDK.Cookie>} cookies 167 * @param {!Array.<!SDK.Cookie>} cookies
115 */ 168 */
116 setCookies(cookies) { 169 setCookies(cookies) {
117 this.setCookieFolders([{cookies: cookies}]); 170 this.setCookieFolders([{cookies: cookies}]);
118 } 171 }
119 172
120 /** 173 /**
121 * @param {!Array.<!{folderName: ?string, cookies: !Array.<!SDK.Cookie>}>} coo kieFolders 174 * @param {!Array.<!{folderName: ?string, cookies: !Array.<!SDK.Cookie>}>} coo kieFolders
122 */ 175 */
123 setCookieFolders(cookieFolders) { 176 setCookieFolders(cookieFolders) {
(...skipping 15 matching lines...) Expand all
139 clear(domain) { 192 clear(domain) {
140 for (var i = 0, length = this._data.length; i < length; ++i) { 193 for (var i = 0, length = this._data.length; i < length; ++i) {
141 var cookies = this._data[i].cookies; 194 var cookies = this._data[i].cookies;
142 for (var j = 0, cookieCount = cookies.length; j < cookieCount; ++j) { 195 for (var j = 0, cookieCount = cookies.length; j < cookieCount; ++j) {
143 if (!domain || cookies[j].domain() === domain) 196 if (!domain || cookies[j].domain() === domain)
144 cookies[j].remove(); 197 cookies[j].remove();
145 } 198 }
146 } 199 }
147 } 200 }
148 201
202 /**
203 * @override
204 */
205 willHide() {
206 this._lastEditedColumnId = null;
207 }
208
149 _rebuildTable() { 209 _rebuildTable() {
150 var selectedCookie = this._nextSelectedCookie || this.selectedCookie(); 210 var selectedCookie = this._nextSelectedCookie || this.selectedCookie();
211 var lastEditedColumnId = this._lastEditedColumnId;
151 this._nextSelectedCookie = null; 212 this._nextSelectedCookie = null;
213 this._lastEditedColumnId = null;
152 this._dataGrid.rootNode().removeChildren(); 214 this._dataGrid.rootNode().removeChildren();
153 for (var i = 0; i < this._data.length; ++i) { 215 for (var i = 0; i < this._data.length; ++i) {
154 var item = this._data[i]; 216 var item = this._data[i];
155 if (item.folderName) { 217 if (item.folderName) {
156 var groupData = { 218 var groupData = {
157 name: item.folderName, 219 name: item.folderName,
158 value: '', 220 value: '',
159 domain: '', 221 domain: '',
160 path: '', 222 path: '',
161 expires: '', 223 expires: '',
162 size: this._totalSize(item.cookies), 224 size: this._totalSize(item.cookies),
163 httpOnly: '', 225 httpOnly: '',
164 secure: '', 226 secure: '',
165 sameSite: '' 227 sameSite: ''
166 }; 228 };
167 var groupNode = new UI.DataGridNode(groupData); 229 var groupNode = new UI.DataGridNode(groupData);
168 groupNode.selectable = true; 230 groupNode.selectable = true;
169 this._dataGrid.rootNode().appendChild(groupNode); 231 this._dataGrid.rootNode().appendChild(groupNode);
170 groupNode.element().classList.add('row-group'); 232 groupNode.element().classList.add('row-group');
171 this._populateNode(groupNode, item.cookies, selectedCookie); 233 this._populateNode(groupNode, item.cookies, selectedCookie, lastEditedCo lumnId);
172 groupNode.expand(); 234 groupNode.expand();
173 } else { 235 } else {
174 this._populateNode(this._dataGrid.rootNode(), item.cookies, selectedCook ie); 236 this._populateNode(this._dataGrid.rootNode(), item.cookies, selectedCook ie, lastEditedColumnId);
175 } 237 }
176 } 238 }
239 if (!this._readOnly)
240 this._dataGrid.addCreationNode(false);
177 } 241 }
178 242
179 /** 243 /**
180 * @param {!UI.DataGridNode} parentNode 244 * @param {!UI.DataGridNode} parentNode
181 * @param {?Array.<!SDK.Cookie>} cookies 245 * @param {?Array.<!SDK.Cookie>} cookies
182 * @param {?SDK.Cookie} selectedCookie 246 * @param {?SDK.Cookie} selectedCookie
247 * @param {?string} lastEditedColumnId
183 */ 248 */
184 _populateNode(parentNode, cookies, selectedCookie) { 249 _populateNode(parentNode, cookies, selectedCookie, lastEditedColumnId) {
185 parentNode.removeChildren(); 250 parentNode.removeChildren();
186 if (!cookies) 251 if (!cookies)
187 return; 252 return;
188 253
189 this._sortCookies(cookies); 254 this._sortCookies(cookies);
190 for (var i = 0; i < cookies.length; ++i) { 255 for (var i = 0; i < cookies.length; ++i) {
191 var cookie = cookies[i]; 256 var cookie = cookies[i];
192 var cookieNode = this._createGridNode(cookie); 257 var cookieNode = this._createGridNode(cookie);
193 parentNode.appendChild(cookieNode); 258 parentNode.appendChild(cookieNode);
194 if (selectedCookie && selectedCookie.name() === cookie.name() && selectedC ookie.domain() === cookie.domain() && 259 if (selectedCookie && selectedCookie.name() === cookie.name() && selectedC ookie.domain() === cookie.domain() &&
195 selectedCookie.path() === cookie.path()) 260 selectedCookie.path() === cookie.path()) {
196 cookieNode.select(); 261 cookieNode.select();
262 if (lastEditedColumnId !== null)
263 this._dataGrid.startEditingNextEditableColumnOfDataGridNode(cookieNode , lastEditedColumnId);
264 }
197 } 265 }
198 } 266 }
199 267
200 _totalSize(cookies) { 268 _totalSize(cookies) {
201 var totalSize = 0; 269 var totalSize = 0;
202 for (var i = 0; cookies && i < cookies.length; ++i) 270 for (var i = 0; cookies && i < cookies.length; ++i)
203 totalSize += cookies[i].size(); 271 totalSize += cookies[i].size();
204 return totalSize; 272 return totalSize;
205 } 273 }
206 274
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 data.path = Common.UIString('N/A'); 346 data.path = Common.UIString('N/A');
279 data.expires = Common.UIString('N/A'); 347 data.expires = Common.UIString('N/A');
280 } else { 348 } else {
281 data.domain = cookie.domain() || ''; 349 data.domain = cookie.domain() || '';
282 data.path = cookie.path() || ''; 350 data.path = cookie.path() || '';
283 if (cookie.maxAge()) 351 if (cookie.maxAge())
284 data.expires = Number.secondsToString(parseInt(cookie.maxAge(), 10)); 352 data.expires = Number.secondsToString(parseInt(cookie.maxAge(), 10));
285 else if (cookie.expires()) 353 else if (cookie.expires())
286 data.expires = new Date(cookie.expires()).toISOString(); 354 data.expires = new Date(cookie.expires()).toISOString();
287 else 355 else
288 data.expires = Common.UIString('Session'); 356 data.expires = Components.CookiesTable._expiresSessionValue;
289 } 357 }
290 data.size = cookie.size(); 358 data.size = cookie.size();
291 const checkmark = '\u2713'; 359 const checkmark = '\u2713';
292 data.httpOnly = (cookie.httpOnly() ? checkmark : ''); 360 data.httpOnly = (cookie.httpOnly() ? checkmark : '');
293 data.secure = (cookie.secure() ? checkmark : ''); 361 data.secure = (cookie.secure() ? checkmark : '');
294 data.sameSite = cookie.sameSite() || ''; 362 data.sameSite = cookie.sameSite() || '';
295 363
296 var node = new UI.DataGridNode(data); 364 var node = new UI.DataGridNode(data);
297 node.cookie = cookie; 365 node.cookie = cookie;
298 node.selectable = true; 366 node.selectable = true;
299 return node; 367 return node;
300 } 368 }
301 369
302 _onDeleteCookie(node) { 370 _onDeleteCookie(node) {
303 var cookie = node.cookie; 371 var cookie = node.cookie;
304 var neighbour = node.traverseNextNode() || node.traversePreviousNode(); 372 var neighbour = node.traverseNextNode() || node.traversePreviousNode();
305 if (neighbour) 373 if (neighbour)
306 this._nextSelectedCookie = neighbour.cookie; 374 this._nextSelectedCookie = neighbour.cookie;
307 cookie.remove(); 375 cookie.remove();
308 this._refresh(); 376 this._refresh();
309 } 377 }
310 378
379 /**
380 * @param {!UI.DataGridNode} editingNode
381 * @param {string} columnIdentifier
382 * @param {string} oldText
383 * @param {string} newText
384 */
385 _onUpdateCookie(editingNode, columnIdentifier, oldText, newText) {
386 this._lastEditedColumnId = columnIdentifier;
387 this._setDefaults(editingNode);
388 if (this._isValidCookieData(editingNode.data))
389 this._saveNode(editingNode);
390 else
391 editingNode.setDirty(true);
392 }
393
394 /**
395 * @param {!UI.DataGridNode} node
396 */
397 _setDefaults(node) {
398 if (node.data.name === null)
399 node.data.name = '';
400 if (node.data.value === null)
401 node.data.value = '';
402 if (node.data.domain === null)
403 node.data.domain = this._cookieDomain;
404 if (node.data.path === null)
405 node.data.path = '/';
406 if (node.data.expires === null)
407 node.data.expires = Components.CookiesTable._expiresSessionValue;
408 }
409
410 /**
411 * @param {!UI.DataGridNode} node
412 */
413 _saveNode(node) {
414 var oldCookie = node.cookie;
415 var newCookie = this._createCookieFromData(node.data);
416 if (oldCookie && (newCookie.name() !== oldCookie.name() || newCookie.url() ! == oldCookie.url()))
417 oldCookie.remove();
418 node.cookie = newCookie;
419 newCookie.save((error, success) => {
420 if (success)
421 this._refresh();
422 else
423 node.setDirty(true);
424 });
425 this._nextSelectedCookie = newCookie;
426 }
427
428 /**
429 * @param {!Object.<string, *>} data
430 * @returns {SDK.Cookie}
431 */
432 _createCookieFromData(data) {
433 var target = SDK.targetManager.targets(SDK.Target.Capability.Network)[0];
434 var cookie = new SDK.Cookie(target, data.name, data.value, null);
435 cookie.addAttribute('domain', data.domain);
436 cookie.addAttribute('path', data.path);
437 if (data.expires && data.expires !== Components.CookiesTable._expiresSession Value)
438 cookie.addAttribute('expires', (new Date(data.expires)).toUTCString());
439 if (data.httpOnly)
440 cookie.addAttribute('httpOnly');
441 if (data.secure)
442 cookie.addAttribute('secure');
443 if (data.sameSite)
444 cookie.addAttribute('sameSite', data.sameSite);
445 cookie.setSize(data.name.length + data.value.length);
446 return cookie;
447 }
448
449 /**
450 * @param {!Object.<string, *>} data
451 * @returns {boolean}
452 */
453 _isValidCookieData(data) {
454 return (data.name || data.value) && this._isValidDomain(data.domain) && this ._isValidPath(data.path) && this._isValidDate(data.expires);
455 }
456
457 /**
458 * @param {string} domain
459 * @returns {boolean}
460 */
461 _isValidDomain(domain) {
462 if (!domain)
463 return true;
464 var parsedURL = ('http://' + domain).asParsedURL();
465 return !!parsedURL && parsedURL.domain() === domain;
466 }
467
468 /**
469 * @param {string} path
470 * @returns {boolean}
471 */
472 _isValidPath(path) {
473 var parsedURL = ('http://example.com' + path).asParsedURL();
474 return !!parsedURL && parsedURL.path === path;
475 }
476
477 /**
478 * @param {string} date
479 * @returns {boolean}
480 */
481 _isValidDate(date) {
482 return date === '' || date === Components.CookiesTable._expiresSessionValue || !isNaN(Date.parse(date));
483 }
484
311 _refresh() { 485 _refresh() {
312 if (this._refreshCallback) 486 if (this._refreshCallback)
313 this._refreshCallback(); 487 this._refreshCallback();
314 } 488 }
315 }; 489 };
490
491 /** @const */
492 Components.CookiesTable._expiresSessionValue = Common.UIString('Session');
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698