2020-04-21 18:56:30 +02:00
|
|
|
/**
|
|
|
|
* @provides phabricator-diff-tree-view
|
|
|
|
* @requires javelin-dom
|
|
|
|
* @javelin
|
|
|
|
*/
|
|
|
|
|
|
|
|
JX.install('DiffTreeView', {
|
|
|
|
|
|
|
|
construct: function() {
|
|
|
|
this._keys = [];
|
|
|
|
this._tree = this._newTreeNode(null, [], 0);
|
|
|
|
this._nodes = {};
|
|
|
|
this._paths = [];
|
|
|
|
},
|
|
|
|
|
|
|
|
members: {
|
|
|
|
_node: null,
|
|
|
|
_keys: null,
|
|
|
|
_tree: null,
|
|
|
|
_nodes: null,
|
|
|
|
_dirty: false,
|
|
|
|
_paths: null,
|
|
|
|
_selectedPath: null,
|
2020-04-21 22:02:36 +02:00
|
|
|
_focusedPath: null,
|
2020-04-21 18:56:30 +02:00
|
|
|
|
|
|
|
getNode: function() {
|
|
|
|
if (!this._node) {
|
2020-04-21 22:02:36 +02:00
|
|
|
var attrs = {
|
|
|
|
className: 'diff-tree-view'
|
|
|
|
};
|
|
|
|
|
|
|
|
this._node = JX.$N('ul', attrs);
|
2020-04-21 18:56:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (this._dirty) {
|
|
|
|
this.redraw();
|
|
|
|
}
|
|
|
|
|
|
|
|
return this._node;
|
|
|
|
},
|
|
|
|
|
|
|
|
addPath: function(path) {
|
|
|
|
this._paths.push(path);
|
|
|
|
|
|
|
|
var tree = this._getTree(this._tree, path.getPath(), 0);
|
|
|
|
tree.pathObject = path;
|
|
|
|
|
|
|
|
this._dirty = true;
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
getPaths: function() {
|
|
|
|
return this._paths;
|
|
|
|
},
|
|
|
|
|
|
|
|
setSelectedPath: function(path) {
|
|
|
|
if (this._selectedPath) {
|
|
|
|
this._selectedPath.setIsSelected(false);
|
|
|
|
this._selectedPath = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (path) {
|
|
|
|
path.setIsSelected(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
this._selectedPath = path;
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2020-04-21 22:02:36 +02:00
|
|
|
setFocusedPath: function(path) {
|
|
|
|
if (this._focusedPath) {
|
|
|
|
this._focusedPath.setIsFocused(false);
|
|
|
|
this._focusedPath = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (path) {
|
|
|
|
path.setIsFocused(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
this._focusedPath = path;
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2020-04-21 18:56:30 +02:00
|
|
|
redraw: function() {
|
|
|
|
if (!this._dirty) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this._dirty = false;
|
|
|
|
|
|
|
|
var ii;
|
|
|
|
|
|
|
|
// For nodes which don't have a path object yet, build one.
|
|
|
|
var tree;
|
2020-04-22 00:52:35 +02:00
|
|
|
var path;
|
2020-04-21 18:56:30 +02:00
|
|
|
var trees = [];
|
|
|
|
for (ii = 0; ii < this._keys.length; ii++) {
|
|
|
|
var key = this._keys[ii];
|
|
|
|
tree = this._nodes[key];
|
2020-04-22 00:52:35 +02:00
|
|
|
path = tree.pathObject;
|
2020-04-21 18:56:30 +02:00
|
|
|
|
|
|
|
if (!path) {
|
|
|
|
path = new JX.DiffPathView()
|
|
|
|
.setPath(tree.parts);
|
2020-04-21 22:02:36 +02:00
|
|
|
|
|
|
|
path.getIcon()
|
2020-04-22 19:56:09 +02:00
|
|
|
.setIcon('fa-folder-open-o')
|
|
|
|
.setColor('grey');
|
2020-04-21 22:02:36 +02:00
|
|
|
|
2020-04-21 18:56:30 +02:00
|
|
|
tree.pathObject = path;
|
|
|
|
}
|
|
|
|
|
|
|
|
trees.push(tree);
|
|
|
|
}
|
|
|
|
|
2020-04-22 00:52:35 +02:00
|
|
|
for (ii = 0; ii < trees.length; ii++) {
|
|
|
|
tree = trees[ii];
|
|
|
|
tree.displayRoot = null;
|
|
|
|
tree.displayPath = null;
|
|
|
|
tree.displayHide = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
var child;
|
|
|
|
for (ii = 0; ii < trees.length; ii++) {
|
|
|
|
tree = trees[ii];
|
|
|
|
|
|
|
|
if (tree.childCount !== 1) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var k in tree.children) {
|
|
|
|
if (tree.children.hasOwnProperty(k)) {
|
|
|
|
child = tree.children[k];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (child.pathObject.getChangeset()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
child.displayRoot = tree.displayRoot || tree;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (ii = 0; ii < trees.length; ii++) {
|
|
|
|
tree = trees[ii];
|
|
|
|
|
|
|
|
if (!tree.displayRoot) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!tree.displayRoot.displayPath) {
|
|
|
|
tree.displayRoot.displayPath = [
|
|
|
|
tree.displayRoot.parts[tree.displayRoot.parts.length - 1]
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
tree.displayRoot.displayPath.push(tree.parts[tree.parts.length - 1]);
|
|
|
|
tree.displayHide = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (ii = 0; ii < trees.length; ii++) {
|
|
|
|
tree = trees[ii];
|
|
|
|
path = tree.pathObject;
|
|
|
|
|
|
|
|
path.setHidden(!!tree.displayHide);
|
|
|
|
|
|
|
|
if (tree.displayPath) {
|
|
|
|
path.setDisplayPath(tree.displayPath.join('/'));
|
|
|
|
} else {
|
|
|
|
path.setDisplayPath(null);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-21 18:56:30 +02:00
|
|
|
for (ii = 0; ii < trees.length; ii++) {
|
|
|
|
tree = trees[ii];
|
|
|
|
|
|
|
|
if (!tree.parent) {
|
|
|
|
tree.depth = 0;
|
|
|
|
} else {
|
2020-04-22 00:52:35 +02:00
|
|
|
// If this node was collapsed into the parent node, don't increase
|
|
|
|
// the tree depth.
|
|
|
|
if (tree.displayHide) {
|
|
|
|
tree.depth = tree.parent.depth;
|
|
|
|
} else {
|
|
|
|
tree.depth = tree.parent.depth + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
path = tree.pathObject;
|
|
|
|
|
|
|
|
if (tree.childCount > 0) {
|
|
|
|
path.setIsDirectory(true);
|
2020-04-21 18:56:30 +02:00
|
|
|
}
|
|
|
|
|
2020-04-22 00:52:35 +02:00
|
|
|
path.setDepth((tree.depth - 1));
|
2020-04-21 18:56:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
var nodes = [];
|
|
|
|
for (ii = 0; ii < trees.length; ii++) {
|
|
|
|
tree = trees[ii];
|
|
|
|
nodes.push(tree.pathObject.getNode());
|
|
|
|
}
|
|
|
|
|
|
|
|
JX.DOM.setContent(this.getNode(), nodes);
|
|
|
|
},
|
|
|
|
|
|
|
|
_getTree: function(root, path, ii) {
|
|
|
|
if (ii >= path.length) {
|
|
|
|
return root;
|
|
|
|
}
|
|
|
|
|
|
|
|
var part = path[ii];
|
|
|
|
|
|
|
|
if (!root.children.hasOwnProperty(part)) {
|
|
|
|
root.children[part] = this._newTreeNode(root, path, ii);
|
|
|
|
root.childCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return this._getTree(root.children[part], path, ii + 1);
|
|
|
|
},
|
|
|
|
|
|
|
|
_newTreeNode: function(parent, path, ii) {
|
|
|
|
var key;
|
|
|
|
var parts;
|
|
|
|
if (path.length) {
|
|
|
|
parts = path.slice(0, ii + 1);
|
|
|
|
key = parts.join('/');
|
|
|
|
this._keys.push(key);
|
|
|
|
} else {
|
|
|
|
parts = [];
|
|
|
|
key = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
var node = {
|
|
|
|
parent: parent,
|
|
|
|
nodeKey: key,
|
|
|
|
parts: parts,
|
|
|
|
children: {},
|
|
|
|
pathObject: null,
|
|
|
|
childCount: 0,
|
|
|
|
depth: 0
|
|
|
|
};
|
|
|
|
|
|
|
|
if (key !== null) {
|
|
|
|
this._nodes[key] = node;
|
|
|
|
}
|
|
|
|
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|