Bug 1014923 - TreeWidget should have an option for unsorted tree. r=bgrins

This commit is contained in:
Gabriel Luong 2014-05-29 08:26:00 -04:00
Родитель c2dff795e4
Коммит ea405c4c4d
2 изменённых файлов: 63 добавлений и 13 удалений

Просмотреть файл

@ -34,6 +34,8 @@ function startTests() {
populateTree();
testTreeItemInsertedCorrectly();
testAPI();
populateUnsortedTree();
testUnsortedTreeItemInsertedCorrectly();
endTests();
}
@ -119,6 +121,41 @@ function testTreeItemInsertedCorrectly() {
"Newly added node is inserted at the right location");
}
/**
* Populate the unsorted tree.
*/
function populateUnsortedTree() {
tree.sorted = false;
tree.add([{ id: "g-1", label: "g-1"}])
tree.add(["g-1", { id: "d-2", label: "d-2.1"}]);
tree.add(["g-1", { id: "b-2", label: "b-2.2"}]);
tree.add(["g-1", { id: "a-2", label: "a-2.3"}]);
}
/**
* Test if the nodes are inserted correctly in the unsorted tree.
*/
function testUnsortedTreeItemInsertedCorrectly() {
ok(tree.root.items.has("g-1"), "g-1 top level element exists");
is(tree.root.children.firstChild.lastChild.children.length, 3,
"Number of children for g-1 matches");
is(tree.root.children.firstChild.dataset.id, JSON.stringify(["g-1"]),
"Data id of g-1 matches");
is(tree.root.children.firstChild.firstChild.textContent, "g-1",
"Text content of g-1 matches");
is(tree.root.children.firstChild.lastChild.firstChild.dataset.id,
JSON.stringify(["g-1", "d-2"]),
"Data id of d-2 matches");
is(tree.root.children.firstChild.lastChild.firstChild.textContent, "d-2.1",
"Text content of d-2 matches");
is(tree.root.children.firstChild.lastChild.firstChild.nextSibling.textContent,
"b-2.2", "Text content of b-2 matches");
is(tree.root.children.firstChild.lastChild.lastChild.textContent, "a-2.3",
"Text content of a-2 matches");
}
/**
* Tests if the API exposed by TreeWidget works properly
*/

Просмотреть файл

@ -18,6 +18,8 @@ const EventEmitter = require("devtools/toolkit/event-emitter");
* @param {Object} options
* - emptyText {string}: text to display when no entries in the table.
* - defaultType {string}: The default type of the tree items. For ex. 'js'
* - sorted {boolean}: Defaults to true. If true, tree items are kept in
* lexical order. If false, items will be kept in insertion order.
*/
function TreeWidget(node, options={}) {
EventEmitter.decorate(this);
@ -26,9 +28,9 @@ function TreeWidget(node, options={}) {
this.window = this.document.defaultView;
this._parent = node;
let {emptyText, defaultType} = options;
this.emptyText = emptyText || "";
this.defaultType = defaultType;
this.emptyText = options.emptyText || "";
this.defaultType = options.defaultType;
this.sorted = options.sorted !== false;
this.setupRoot();
@ -245,7 +247,7 @@ TreeWidget.prototype = {
* its id.
*/
add: function(items) {
this.root.add(items, this.defaultType);
this.root.add(items, this.defaultType, this.sorted);
for (let i = 0; i < items.length; i++) {
if (items[i].attachment) {
this.attachments.set(JSON.stringify(
@ -459,8 +461,11 @@ TreeItem.prototype = {
* Same as TreeWidget.add method's argument
* @param {string} defaultType
* The default type of the item to be used when items[i].type is null
* @param {boolean} sorted
* true if the tree items are inserted in a lexically sorted manner.
* Otherwise, false if the item are to be appended to their parent.
*/
add: function(items, defaultType) {
add: function(items, defaultType, sorted) {
if (items.length == this.level) {
// This is the exit condition of recursive TreeItem.add calls
return;
@ -470,7 +475,7 @@ TreeItem.prototype = {
if (this.items.has(id)) {
// An item with same id already exists, thus calling the add method of that
// child to add the passed node at correct position.
this.items.get(id).add(items, defaultType);
this.items.get(id).add(items, defaultType, sorted);
return;
}
// No item with the id `id` exists, so we create one and call the add
@ -486,19 +491,27 @@ TreeItem.prototype = {
}
let treeItem = new TreeItem(this.document, this, node || label,
items[this.level].type || defaultType);
let nextSibling = [...this.items.values()].find(child => {
return child.label.textContent >= label;
});
treeItem.add(items, defaultType);
treeItem.add(items, defaultType, sorted);
treeItem.node.setAttribute("data-id", JSON.stringify(
items.slice(0, this.level + 1).map(item => item.id || item)
));
// Inserting this newly created item at correct position
if (nextSibling) {
this.children.insertBefore(treeItem.node, nextSibling.node);
if (sorted) {
// Inserting this newly created item at correct position
let nextSibling = [...this.items.values()].find(child => {
return child.label.textContent >= label;
});
if (nextSibling) {
this.children.insertBefore(treeItem.node, nextSibling.node);
} else {
this.children.appendChild(treeItem.node);
}
} else {
this.children.appendChild(treeItem.node);
}
if (this.label) {
this.label.removeAttribute("empty");
}