blob: 42187de5cb089b6071c215b3392dd49279ff5395 [file] [log] [blame]
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
cr.define('ui', function() {
const Tree = cr.ui.Tree;
const TreeItem = cr.ui.TreeItem;
/**
* Creates a new tree item for sites data.
* @param {Object=} data Data used to create a cookie tree item.
* @constructor
* @extends {TreeItem}
*/
function CookiesTreeItem(data) {
var treeItem = new TreeItem({
label: data.title,
data: data
});
treeItem.__proto__ = CookiesTreeItem.prototype;
if (data.icon)
treeItem.icon = data.icon;
treeItem.decorate();
return treeItem;
}
CookiesTreeItem.prototype = {
__proto__: TreeItem.prototype,
/** @inheritDoc */
decorate: function() {
this.hasChildren = this.data.hasChildren;
},
/** @inheritDoc */
addAt: function(child, index) {
TreeItem.prototype.addAt.call(this, child, index);
if (child.data && child.data.id)
this.tree.treeLookup[child.data.id] = child;
},
/** @inheritDoc */
remove: function(child) {
TreeItem.prototype.remove.call(this, child);
if (child.data && child.data.id)
delete this.tree.treeLookup[child.data.id];
},
/**
* Clears all children.
*/
clear: function() {
// We might leave some garbage in treeLookup for removed children.
// But that should be okay because treeLookup is cleared when we
// reload the tree.
this.lastElementChild.textContent = '';
},
/**
* The tree path id.
* @type {string}
*/
get pathId() {
var parent = this.parentItem;
if (parent instanceof CookiesTreeItem)
return parent.pathId + ',' + this.data.id;
else
return this.data.id;
},
/** @inheritDoc */
get expanded() {
return TreeItem.prototype.__lookupGetter__('expanded').call(this);
},
set expanded(b) {
if (b && this.expanded != b)
chrome.send(this.tree.requestChildrenMessage, [this.pathId]);
TreeItem.prototype.__lookupSetter__('expanded').call(this, b);
}
};
/**
* Creates a new cookies tree.
* @param {Object=} opt_propertyBag Optional properties.
* @constructor
* @extends {Tree}
*/
var CookiesTree = cr.ui.define('tree');
CookiesTree.prototype = {
__proto__: Tree.prototype,
/**
* Per-tree dict to map from data.id to tree node.
*/
treeLookup_: null,
get treeLookup() {
if (!this.treeLookup_)
this.treeLookup_ = {};
return this.treeLookup_;
},
/** @inheritDoc */
addAt: function(child, index) {
Tree.prototype.addAt.call(this, child, index);
if (child.data && child.data.id)
this.treeLookup[child.data.id] = child;
},
/** @inheritDoc */
remove: function(child) {
Tree.prototype.remove.call(this, child);
if (child.data && child.data.id)
delete this.treeLookup[child.data.id];
},
/**
* Add tree nodes by given parent.
* @param {Object} parent Parent node.
* @param {number} start Start index of where to insert nodes.
* @param {Array} nodesData Nodes data array.
*/
addByParent: function(parent, start, nodesData) {
for (var i = 0; i < nodesData.length; ++i) {
parent.addAt(new CookiesTreeItem(nodesData[i]), start + i);
}
cr.dispatchSimpleEvent(this, 'change');
},
/**
* Add tree nodes by parent id.
* @param {string} parentId Id of the parent node.
* @param {int} start Start index of where to insert nodes.
* @param {Array} nodesData Nodes data array.
*/
addByParentId: function(parentId, start, nodesData) {
var parent = parentId ? this.treeLookup[parentId] : this;
this.addByParent(parent, start, nodesData);
},
/**
* Removes tree nodes by parent id.
* @param {string} parentId Id of the parent node.
* @param {int} start Start index of nodes to remove.
* @param {int} count Number of nodes to remove.
*/
removeByParentId: function(parentId, start, count) {
var parent = parentId ? this.treeLookup[parentId] : this;
for (; count > 0 && parent.items.length; --count) {
parent.remove(parent.items[start]);
}
cr.dispatchSimpleEvent(this, 'change');
},
/**
* Clears the tree.
*/
clear: function() {
// Remove all fields without recreating the object since other code
// references it.
for (var id in this.treeLookup){
delete this.treeLookup[id];
}
this.textContent = '';
},
/**
* Unique 'requestChildren' callback message name to send request to
* underlying CookiesTreeModelAdapter.
* @type {string}
*/
requestChildrenMessage_ : null,
get requestChildrenMessage() {
return this.requestChildrenMessage_;
},
/**
* Set callback message name.
* @param {string} loadChildren Message name for 'loadChildren' request.
*/
doSetCallback: function(loadChildren) {
this.requestChildrenMessage_ = loadChildren;
},
/**
* Sets the immediate children of given parent node.
* @param {string} parentId Id of the parent node.
* @param {Array} children The immediate children of parent node.
*/
doSetChildren: function(parentId, children) {
var parent = parentId ? this.treeLookup[parentId] : this;
parent.clear();
this.addByParent(parent, 0, children);
}
};
// CookiesTreeModelAdapter callbacks.
CookiesTree.setCallback = function(treeId, message) {
$(treeId).doSetCallback(message);
}
CookiesTree.onTreeItemAdded = function(treeId, parentId, start, children) {
$(treeId).addByParentId(parentId, start, children);
}
CookiesTree.onTreeItemRemoved = function(treeId, parentId, start, count) {
$(treeId).removeByParentId(parentId, start, count);
}
CookiesTree.setChildren = function(treeId, parentId, children) {
$(treeId).doSetChildren(parentId, children);
}
return {
CookiesTree: CookiesTree
};
});