cookies_tree.js revision ddb351dbec246cf1fab5ec20d2d5520909041de1
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