1// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5cr.define('ui', function() { 6 const Tree = cr.ui.Tree; 7 const TreeItem = cr.ui.TreeItem; 8 9 /** 10 * Creates a new tree item for sites data. 11 * @param {Object=} data Data used to create a cookie tree item. 12 * @constructor 13 * @extends {TreeItem} 14 */ 15 function CookiesTreeItem(data) { 16 var treeItem = new TreeItem({ 17 label: data.title, 18 data: data 19 }); 20 treeItem.__proto__ = CookiesTreeItem.prototype; 21 22 if (data.icon) 23 treeItem.icon = data.icon; 24 25 treeItem.decorate(); 26 return treeItem; 27 } 28 29 CookiesTreeItem.prototype = { 30 __proto__: TreeItem.prototype, 31 32 /** @inheritDoc */ 33 decorate: function() { 34 this.hasChildren = this.data.hasChildren; 35 }, 36 37 /** @inheritDoc */ 38 addAt: function(child, index) { 39 TreeItem.prototype.addAt.call(this, child, index); 40 if (child.data && child.data.id) 41 this.tree.treeLookup[child.data.id] = child; 42 }, 43 44 /** @inheritDoc */ 45 remove: function(child) { 46 TreeItem.prototype.remove.call(this, child); 47 if (child.data && child.data.id) 48 delete this.tree.treeLookup[child.data.id]; 49 }, 50 51 /** 52 * Clears all children. 53 */ 54 clear: function() { 55 // We might leave some garbage in treeLookup for removed children. 56 // But that should be okay because treeLookup is cleared when we 57 // reload the tree. 58 this.lastElementChild.textContent = ''; 59 }, 60 61 /** 62 * The tree path id. 63 * @type {string} 64 */ 65 get pathId() { 66 var parent = this.parentItem; 67 if (parent instanceof CookiesTreeItem) 68 return parent.pathId + ',' + this.data.id; 69 else 70 return this.data.id; 71 }, 72 73 /** @inheritDoc */ 74 get expanded() { 75 return TreeItem.prototype.__lookupGetter__('expanded').call(this); 76 }, 77 set expanded(b) { 78 if (b && this.expanded != b) 79 chrome.send(this.tree.requestChildrenMessage, [this.pathId]); 80 81 TreeItem.prototype.__lookupSetter__('expanded').call(this, b); 82 } 83 }; 84 85 /** 86 * Creates a new cookies tree. 87 * @param {Object=} opt_propertyBag Optional properties. 88 * @constructor 89 * @extends {Tree} 90 */ 91 var CookiesTree = cr.ui.define('tree'); 92 93 CookiesTree.prototype = { 94 __proto__: Tree.prototype, 95 96 /** 97 * Per-tree dict to map from data.id to tree node. 98 */ 99 treeLookup_: null, 100 get treeLookup() { 101 if (!this.treeLookup_) 102 this.treeLookup_ = {}; 103 return this.treeLookup_; 104 }, 105 106 /** @inheritDoc */ 107 addAt: function(child, index) { 108 Tree.prototype.addAt.call(this, child, index); 109 if (child.data && child.data.id) 110 this.treeLookup[child.data.id] = child; 111 }, 112 113 /** @inheritDoc */ 114 remove: function(child) { 115 Tree.prototype.remove.call(this, child); 116 if (child.data && child.data.id) 117 delete this.treeLookup[child.data.id]; 118 }, 119 120 /** 121 * Add tree nodes by given parent. 122 * @param {Object} parent Parent node. 123 * @param {number} start Start index of where to insert nodes. 124 * @param {Array} nodesData Nodes data array. 125 */ 126 addByParent: function(parent, start, nodesData) { 127 for (var i = 0; i < nodesData.length; ++i) { 128 parent.addAt(new CookiesTreeItem(nodesData[i]), start + i); 129 } 130 131 cr.dispatchSimpleEvent(this, 'change'); 132 }, 133 134 /** 135 * Add tree nodes by parent id. 136 * @param {string} parentId Id of the parent node. 137 * @param {int} start Start index of where to insert nodes. 138 * @param {Array} nodesData Nodes data array. 139 */ 140 addByParentId: function(parentId, start, nodesData) { 141 var parent = parentId ? this.treeLookup[parentId] : this; 142 this.addByParent(parent, start, nodesData); 143 }, 144 145 /** 146 * Removes tree nodes by parent id. 147 * @param {string} parentId Id of the parent node. 148 * @param {int} start Start index of nodes to remove. 149 * @param {int} count Number of nodes to remove. 150 */ 151 removeByParentId: function(parentId, start, count) { 152 var parent = parentId ? this.treeLookup[parentId] : this; 153 154 for (; count > 0 && parent.items.length; --count) { 155 parent.remove(parent.items[start]); 156 } 157 158 cr.dispatchSimpleEvent(this, 'change'); 159 }, 160 161 /** 162 * Clears the tree. 163 */ 164 clear: function() { 165 // Remove all fields without recreating the object since other code 166 // references it. 167 for (var id in this.treeLookup){ 168 delete this.treeLookup[id]; 169 } 170 this.textContent = ''; 171 }, 172 173 /** 174 * Unique 'requestChildren' callback message name to send request to 175 * underlying CookiesTreeModelAdapter. 176 * @type {string} 177 */ 178 requestChildrenMessage_ : null, 179 get requestChildrenMessage() { 180 return this.requestChildrenMessage_; 181 }, 182 183 /** 184 * Set callback message name. 185 * @param {string} loadChildren Message name for 'loadChildren' request. 186 */ 187 doSetCallback: function(loadChildren) { 188 this.requestChildrenMessage_ = loadChildren; 189 }, 190 191 /** 192 * Sets the immediate children of given parent node. 193 * @param {string} parentId Id of the parent node. 194 * @param {Array} children The immediate children of parent node. 195 */ 196 doSetChildren: function(parentId, children) { 197 var parent = parentId ? this.treeLookup[parentId] : this; 198 199 parent.clear(); 200 this.addByParent(parent, 0, children); 201 } 202 }; 203 204 // CookiesTreeModelAdapter callbacks. 205 CookiesTree.setCallback = function(treeId, message) { 206 $(treeId).doSetCallback(message); 207 } 208 209 CookiesTree.onTreeItemAdded = function(treeId, parentId, start, children) { 210 $(treeId).addByParentId(parentId, start, children); 211 } 212 213 CookiesTree.onTreeItemRemoved = function(treeId, parentId, start, count) { 214 $(treeId).removeByParentId(parentId, start, count); 215 } 216 217 CookiesTree.setChildren = function(treeId, parentId, children) { 218 $(treeId).doSetChildren(parentId, children); 219 } 220 221 return { 222 CookiesTree: CookiesTree 223 }; 224}); 225