OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 cr.define('options', function() { | 5 cr.define('options', function() { |
6 /** @const */ var DeletableItemList = options.DeletableItemList; | 6 /** @const */ var DeletableItemList = options.DeletableItemList; |
7 /** @const */ var DeletableItem = options.DeletableItem; | 7 /** @const */ var DeletableItem = options.DeletableItem; |
8 /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; | 8 /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; |
9 /** @const */ var ListSingleSelectionModel = cr.ui.ListSingleSelectionModel; | 9 /** @const */ var ListSingleSelectionModel = cr.ui.ListSingleSelectionModel; |
10 | 10 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 var nodes = data.map(function(x) { return new CookieTreeNode(x); }); | 70 var nodes = data.map(function(x) { return new CookieTreeNode(x); }); |
71 // Insert [start, 0] at the beginning of the array of nodes, making it | 71 // Insert [start, 0] at the beginning of the array of nodes, making it |
72 // into the arguments we want to pass to @{code list.splice} below. | 72 // into the arguments we want to pass to @{code list.splice} below. |
73 nodes.splice(0, 0, start, 0); | 73 nodes.splice(0, 0, start, 0); |
74 list.splice.apply(list, nodes); | 74 list.splice.apply(list, nodes); |
75 // Remove the [start, 0] prefix and return the array of nodes. | 75 // Remove the [start, 0] prefix and return the array of nodes. |
76 nodes.splice(0, 2); | 76 nodes.splice(0, 2); |
77 return nodes; | 77 return nodes; |
78 } | 78 } |
79 | 79 |
| 80 /** |
| 81 * Adds information about an app that protects this data item to the |
| 82 * @{code element}. |
| 83 * @param {Element} element The DOM element the information should be |
| 84 appended to. |
| 85 * @param {{id: string, name: string}} appInfo Information about an app. |
| 86 */ |
| 87 function addAppInfo(element, appInfo) { |
| 88 var img = element.ownerDocument.createElement('img'); |
| 89 img.src = 'chrome://extension-icon/' + appInfo.id + '/16/1'; |
| 90 img.title = loadTimeData.getString('label_protected_by_apps') + |
| 91 ' ' + appInfo.name; |
| 92 img.className = 'protecting-app'; |
| 93 element.appendChild(img); |
| 94 } |
| 95 |
80 var parentLookup = {}; | 96 var parentLookup = {}; |
81 var lookupRequests = {}; | 97 var lookupRequests = {}; |
82 | 98 |
83 /** | 99 /** |
84 * Creates a new list item for sites data. Note that these are created and | 100 * Creates a new list item for sites data. Note that these are created and |
85 * destroyed lazily as they scroll into and out of view, so they must be | 101 * destroyed lazily as they scroll into and out of view, so they must be |
86 * stateless. We cache the expanded item in @{code CookiesList} though, so it | 102 * stateless. We cache the expanded item in @{code CookiesList} though, so it |
87 * can keep state. (Mostly just which item is selected.) | 103 * can keep state. (Mostly just which item is selected.) |
88 * @param {Object} origin Data used to create a cookie list item. | 104 * @param {Object} origin Data used to create a cookie list item. |
89 * @param {CookiesList} list The list that will contain this item. | 105 * @param {CookiesList} list The list that will contain this item. |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 cookies: 0, | 248 cookies: 0, |
233 database: false, | 249 database: false, |
234 localStorage: false, | 250 localStorage: false, |
235 appCache: false, | 251 appCache: false, |
236 indexedDb: false, | 252 indexedDb: false, |
237 fileSystem: false, | 253 fileSystem: false, |
238 serverBoundCerts: 0, | 254 serverBoundCerts: 0, |
239 }; | 255 }; |
240 if (this.origin) | 256 if (this.origin) |
241 this.origin.collectSummaryInfo(info); | 257 this.origin.collectSummaryInfo(info); |
| 258 |
242 var list = []; | 259 var list = []; |
243 if (info.cookies > 1) | 260 if (info.cookies > 1) |
244 list.push(loadTimeData.getStringF('cookie_plural', info.cookies)); | 261 list.push(loadTimeData.getStringF('cookie_plural', info.cookies)); |
245 else if (info.cookies > 0) | 262 else if (info.cookies > 0) |
246 list.push(loadTimeData.getString('cookie_singular')); | 263 list.push(loadTimeData.getString('cookie_singular')); |
247 if (info.database || info.indexedDb) | 264 if (info.database || info.indexedDb) |
248 list.push(loadTimeData.getString('cookie_database_storage')); | 265 list.push(loadTimeData.getString('cookie_database_storage')); |
249 if (info.localStorage) | 266 if (info.localStorage) |
250 list.push(loadTimeData.getString('cookie_local_storage')); | 267 list.push(loadTimeData.getString('cookie_local_storage')); |
251 if (info.appCache) | 268 if (info.appCache) |
252 list.push(loadTimeData.getString('cookie_app_cache')); | 269 list.push(loadTimeData.getString('cookie_app_cache')); |
253 if (info.fileSystem) | 270 if (info.fileSystem) |
254 list.push(loadTimeData.getString('cookie_file_system')); | 271 list.push(loadTimeData.getString('cookie_file_system')); |
255 if (info.serverBoundCerts) | 272 if (info.serverBoundCerts) |
256 list.push(loadTimeData.getString('cookie_server_bound_cert')); | 273 list.push(loadTimeData.getString('cookie_server_bound_cert')); |
| 274 |
257 var text = ''; | 275 var text = ''; |
258 for (var i = 0; i < list.length; ++i) | 276 for (var i = 0; i < list.length; ++i) { |
259 if (text.length > 0) | 277 if (text.length > 0) |
260 text += ', ' + list[i]; | 278 text += ', ' + list[i]; |
261 else | 279 else |
262 text = list[i]; | 280 text = list[i]; |
| 281 } |
263 this.dataChild.textContent = text; | 282 this.dataChild.textContent = text; |
264 if (info.quota && info.quota.totalUsage) { | 283 |
| 284 for (var key in info.appsProtectingThis) { |
| 285 addAppInfo(this.dataChild, apps[key]); |
| 286 } |
| 287 |
| 288 if (info.quota && info.quota.totalUsage) |
265 this.sizeChild.textContent = info.quota.totalUsage; | 289 this.sizeChild.textContent = info.quota.totalUsage; |
266 } | |
267 | 290 |
268 if (this.expanded) | 291 if (this.expanded) |
269 this.updateItems_(); | 292 this.updateItems_(); |
270 }, | 293 }, |
271 | 294 |
272 /** | 295 /** |
273 * Updates the items section to reflect changes, animating to the new state. | 296 * Updates the items section to reflect changes, animating to the new state. |
274 * Removes existing contents and calls @{code CookieTreeNode.createItems}. | 297 * Removes existing contents and calls @{code CookieTreeNode.createItems}. |
275 * @private | 298 * @private |
276 */ | 299 */ |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
455 info.appCache = true; | 478 info.appCache = true; |
456 } else if (this.data.type == 'indexed_db') { | 479 } else if (this.data.type == 'indexed_db') { |
457 info.indexedDb = true; | 480 info.indexedDb = true; |
458 } else if (this.data.type == 'file_system') { | 481 } else if (this.data.type == 'file_system') { |
459 info.fileSystem = true; | 482 info.fileSystem = true; |
460 } else if (this.data.type == 'quota') { | 483 } else if (this.data.type == 'quota') { |
461 info.quota = this.data; | 484 info.quota = this.data; |
462 } else if (this.data.type == 'server_bound_cert') { | 485 } else if (this.data.type == 'server_bound_cert') { |
463 info.serverBoundCerts++; | 486 info.serverBoundCerts++; |
464 } | 487 } |
| 488 |
| 489 var apps = this.data.appsProtectingThis; |
| 490 if (apps) { |
| 491 if (!info.appsProtectingThis) |
| 492 info.appsProtectingThis = {}; |
| 493 apps.forEach(function(appInfo) { |
| 494 info.appsProtectingThis[appInfo.id] = appInfo; |
| 495 }); |
| 496 } |
465 } | 497 } |
466 }, | 498 }, |
467 | 499 |
468 /** | 500 /** |
469 * Create the cookie "bubbles" for this node, recursing into children | 501 * Create the cookie "bubbles" for this node, recursing into children |
470 * if there are any. Append the cookie bubbles to @{code item}. | 502 * if there are any. Append the cookie bubbles to @{code item}. |
471 * @param {CookieListItem} item The cookie list item to create items in. | 503 * @param {CookieListItem} item The cookie list item to create items in. |
472 */ | 504 */ |
473 createItems: function(item) { | 505 createItems: function(item) { |
474 if (this.children.length > 0) { | 506 if (this.children.length > 0) { |
475 for (var i = 0; i < this.children.length; ++i) | 507 for (var i = 0; i < this.children.length; ++i) |
476 this.children[i].createItems(item); | 508 this.children[i].createItems(item); |
477 } else if (this.data && !this.data.hasChildren) { | 509 return; |
478 var text = ''; | |
479 switch (this.data.type) { | |
480 case 'cookie': | |
481 case 'database': | |
482 text = this.data.name; | |
483 break; | |
484 case 'local_storage': | |
485 text = loadTimeData.getString('cookie_local_storage'); | |
486 break; | |
487 case 'app_cache': | |
488 text = loadTimeData.getString('cookie_app_cache'); | |
489 break; | |
490 case 'indexed_db': | |
491 text = loadTimeData.getString('cookie_indexed_db'); | |
492 break; | |
493 case 'file_system': | |
494 text = loadTimeData.getString('cookie_file_system'); | |
495 break; | |
496 case 'server_bound_cert': | |
497 text = loadTimeData.getString('cookie_server_bound_cert'); | |
498 break; | |
499 } | |
500 if (!text) | |
501 return; | |
502 var div = item.ownerDocument.createElement('div'); | |
503 div.className = 'cookie-item'; | |
504 // Help out screen readers and such: this is a clickable thing. | |
505 div.setAttribute('role', 'button'); | |
506 div.textContent = text; | |
507 var index = item.appendItem(this, div); | |
508 div.onclick = function() { | |
509 if (item.selectedIndex == index) | |
510 item.selectedIndex = -1; | |
511 else | |
512 item.selectedIndex = index; | |
513 }; | |
514 } | 510 } |
| 511 |
| 512 if (!this.data || this.data.hasChildren) |
| 513 return; |
| 514 |
| 515 var text = ''; |
| 516 switch (this.data.type) { |
| 517 case 'cookie': |
| 518 case 'database': |
| 519 text = this.data.name; |
| 520 break; |
| 521 default: |
| 522 text = loadTimeData.getString('cookie_' + this.data.type); |
| 523 } |
| 524 if (!text) |
| 525 return; |
| 526 |
| 527 var div = item.ownerDocument.createElement('div'); |
| 528 div.className = 'cookie-item'; |
| 529 // Help out screen readers and such: this is a clickable thing. |
| 530 div.setAttribute('role', 'button'); |
| 531 div.tabIndex = 0; |
| 532 div.textContent = text; |
| 533 var apps = this.data.appsProtectingThis; |
| 534 if (apps) |
| 535 apps.forEach(addAppInfo.bind(null, div)); |
| 536 |
| 537 var index = item.appendItem(this, div); |
| 538 div.onclick = function() { |
| 539 item.selectedIndex = (item.selectedIndex == index) ? -1 : index; |
| 540 }; |
515 }, | 541 }, |
516 | 542 |
517 /** | 543 /** |
518 * Set the detail text to be displayed to that of this cookie tree node. | 544 * Set the detail text to be displayed to that of this cookie tree node. |
519 * Uses preallocated DOM elements for each cookie node type from @{code | 545 * Uses preallocated DOM elements for each cookie node type from @{code |
520 * infoNodes}, and inserts the appropriate elements to @{code element}. | 546 * infoNodes}, and inserts the appropriate elements to @{code element}. |
521 * @param {Element} element The DOM element to insert elements to. | 547 * @param {Element} element The DOM element to insert elements to. |
522 * @param {Object.<string, {table: Element, info: Object.<string, | 548 * @param {Object.<string, {table: Element, info: Object.<string, |
523 * Element>}>} infoNodes The map from cookie node types to maps from | 549 * Element>}>} infoNodes The map from cookie node types to maps from |
524 * cookie attribute names to DOM elements to display cookie attribute | 550 * cookie attribute names to DOM elements to display cookie attribute |
525 * values, created by @{code CookiesList.decorate}. | 551 * values, created by @{code CookiesList.decorate}. |
526 */ | 552 */ |
527 setDetailText: function(element, infoNodes) { | 553 setDetailText: function(element, infoNodes) { |
528 var table; | 554 var table; |
529 if (this.data && !this.data.hasChildren) { | 555 if (this.data && !this.data.hasChildren && cookieInfo[this.data.type]) { |
530 if (cookieInfo[this.data.type]) { | 556 var info = cookieInfo[this.data.type]; |
531 var info = cookieInfo[this.data.type]; | 557 var nodes = infoNodes[this.data.type].info; |
532 var nodes = infoNodes[this.data.type].info; | 558 for (var i = 0; i < info.length; ++i) { |
533 for (var i = 0; i < info.length; ++i) { | 559 var name = info[i][0]; |
534 var name = info[i][0]; | 560 if (name != 'id' && this.data[name]) |
535 if (name != 'id' && this.data[name]) | 561 nodes[name].textContent = this.data[name]; |
536 nodes[name].textContent = this.data[name]; | 562 else |
537 else | 563 nodes[name].textContent = ''; |
538 nodes[name].textContent = ''; | |
539 } | |
540 table = infoNodes[this.data.type].table; | |
541 } | 564 } |
| 565 table = infoNodes[this.data.type].table; |
542 } | 566 } |
| 567 |
543 while (element.childNodes.length > 1) | 568 while (element.childNodes.length > 1) |
544 element.removeChild(element.firstChild); | 569 element.removeChild(element.firstChild); |
| 570 |
545 if (table) | 571 if (table) |
546 element.insertBefore(table, element.firstChild); | 572 element.insertBefore(table, element.firstChild); |
547 }, | 573 }, |
548 | 574 |
549 /** | 575 /** |
550 * The parent of this cookie tree node. | 576 * The parent of this cookie tree node. |
551 * @type {?CookieTreeNode|CookieListItem} | 577 * @type {?CookieTreeNode|CookieListItem} |
552 */ | 578 */ |
553 get parent() { | 579 get parent() { |
554 // See below for an explanation of this special case. | 580 // See below for an explanation of this special case. |
555 if (typeof this.parent_ == 'number') | 581 if (typeof this.parent_ == 'number') |
556 return this.list_.getListItemByIndex(this.parent_); | 582 return this.list_.getListItemByIndex(this.parent_); |
557 return this.parent_; | 583 return this.parent_; |
558 }, | 584 }, |
559 set parent(parent) { | 585 set parent(parent) { |
560 if (parent == this.parent) | 586 if (parent == this.parent) |
561 return; | 587 return; |
| 588 |
562 if (parent instanceof CookieListItem) { | 589 if (parent instanceof CookieListItem) { |
563 // If the parent is to be a CookieListItem, then we keep the reference | 590 // If the parent is to be a CookieListItem, then we keep the reference |
564 // to it by its containing list and list index, rather than directly. | 591 // to it by its containing list and list index, rather than directly. |
565 // This allows the list items to be garbage collected when they scroll | 592 // This allows the list items to be garbage collected when they scroll |
566 // out of view (except the expanded item, which we cache). This is | 593 // out of view (except the expanded item, which we cache). This is |
567 // transparent except in the setter and getter, where we handle it. | 594 // transparent except in the setter and getter, where we handle it. |
568 this.parent_ = parent.listIndex; | 595 this.parent_ = parent.listIndex; |
569 this.list_ = parent.list; | 596 this.list_ = parent.list; |
570 parent.addEventListener('listIndexChange', | 597 parent.addEventListener('listIndexChange', |
571 this.parentIndexChanged_.bind(this)); | 598 this.parentIndexChanged_.bind(this)); |
572 } else { | 599 } else { |
573 this.parent_ = parent; | 600 this.parent_ = parent; |
574 } | 601 } |
| 602 |
575 if (this.data && this.data.id) { | 603 if (this.data && this.data.id) { |
576 if (parent) | 604 if (parent) |
577 parentLookup[this.data.id] = this; | 605 parentLookup[this.data.id] = this; |
578 else | 606 else |
579 delete parentLookup[this.data.id]; | 607 delete parentLookup[this.data.id]; |
580 } | 608 } |
| 609 |
581 if (this.data && this.data.hasChildren && | 610 if (this.data && this.data.hasChildren && |
582 !this.children.length && !lookupRequests[this.data.id]) { | 611 !this.children.length && !lookupRequests[this.data.id]) { |
583 lookupRequests[this.data.id] = true; | 612 lookupRequests[this.data.id] = true; |
584 chrome.send('loadCookie', [this.pathId]); | 613 chrome.send('loadCookie', [this.pathId]); |
585 } | 614 } |
586 }, | 615 }, |
587 | 616 |
588 /** | 617 /** |
589 * Called when the parent is a CookieListItem whose index has changed. | 618 * Called when the parent is a CookieListItem whose index has changed. |
590 * See the code above that avoids keeping a direct reference to | 619 * See the code above that avoids keeping a direct reference to |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
860 parent.clear(); | 889 parent.clear(); |
861 this.addByParent_(parent, 0, children); | 890 this.addByParent_(parent, 0, children); |
862 parent.endBatchUpdates(); | 891 parent.endBatchUpdates(); |
863 }, | 892 }, |
864 }; | 893 }; |
865 | 894 |
866 return { | 895 return { |
867 CookiesList: CookiesList | 896 CookiesList: CookiesList |
868 }; | 897 }; |
869 }); | 898 }); |
OLD | NEW |