Index: ui/file_manager/file_manager/foreground/js/ui/directory_tree.js |
diff --git a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js |
index 11f2dc607c59841cb31589b6fcbcfe40cba82023..3cd331ef1656cd4bcbf89f9d6ae84a7d703302b0 100644 |
--- a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js |
+++ b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js |
@@ -92,7 +92,6 @@ var MENU_TREE_ITEM_INNER_HTML = |
function DirectoryItem(label, tree) { |
var item = new cr.ui.TreeItem(); |
item.__proto__ = DirectoryItem.prototype; |
- |
item.parentTree_ = tree; |
item.directoryModel_ = tree.directoryModel; |
item.fileFilter_ = tree.directoryModel.getFileFilter(); |
@@ -100,6 +99,15 @@ function DirectoryItem(label, tree) { |
item.innerHTML = TREE_ITEM_INNER_HTML; |
item.addEventListener('expand', item.onExpand_.bind(item), false); |
+ // Listen for collapse because for the delayed expansion case all |
+ // children are also collapsed. |
+ item.addEventListener('collapse', item.onCollapse_.bind(item), false); |
+ |
+ // Default delayExpansion to false. Volumes will set it to true for |
+ // provided file systems. SubDirectories will inherit from their |
+ // parent. |
+ item.delayExpansion = false; |
+ |
// Sets hasChildren=false tentatively. This will be overridden after |
// scanning sub-directories in updateSubElementsFromList(). |
item.hasChildren = false; |
@@ -155,8 +163,19 @@ DirectoryItem.prototype.updateSubElementsFromList = function(recursive) { |
index++; |
} else if (util.isSameEntry(currentEntry, currentElement.entry)) { |
currentElement.updateSharedStatusIcon(); |
- if (recursive && this.expanded) |
- currentElement.updateSubDirectories(true /* recursive */); |
+ if (recursive && this.expanded) { |
+ if (this.delayExpansion) { |
+ // Only update deeper on expanded children. |
+ if (currentElement.expanded) { |
+ currentElement.updateSubDirectories(true /* recursive */); |
+ } |
+ |
+ // Show the expander even without knowing if there are children. |
+ currentElement.mayHaveChildren_ = true; |
+ } else { |
+ currentElement.updateSubDirectories(true /* recursive */); |
+ } |
+ } |
index++; |
} else if (currentEntry.toURL() < currentElement.entry.toURL()) { |
var item = new SubDirectoryItem(label, currentEntry, this, tree); |
@@ -224,6 +243,18 @@ DirectoryItem.prototype.remove = function(child) { |
this.hasChildren = false; |
}; |
+ |
+/** |
+ * Removes the has-children attribute which allows returning |
+ * to the ambiguous may-have-children state. |
+ */ |
+DirectoryItem.prototype.clearHasChildren = function() { |
+ var rowItem = this.firstElementChild; |
+ this.removeAttribute('has-children'); |
+ rowItem.removeAttribute('has-children'); |
+}; |
+ |
+ |
/** |
* Invoked when the item is being expanded. |
* @param {!Event} e Event. |
@@ -240,6 +271,30 @@ DirectoryItem.prototype.onExpand_ = function(e) { |
e.stopPropagation(); |
}; |
+ |
+/** |
+ * Invoked when the item is being collapsed. |
+ * @param {!Event} e Event. |
+ * @private |
+ */ |
+DirectoryItem.prototype.onCollapse_ = function(e) { |
+ if (this.delayExpansion) { |
+ // For file systems where it is performance intensive |
+ // to update recursively when items expand this proactively |
+ // collapses all children to avoid having to traverse large |
+ // parts of the tree when reopened. |
+ for (var i = 0; i < this.items.length; i++) { |
+ var item = this.items[i]; |
+ |
+ if (item.expanded) { |
+ item.expanded = false; |
+ } |
+ } |
+ } |
+ |
+ e.stopPropagation(); |
+}; |
+ |
/** |
* Invoked when the tree item is clicked. |
* |
@@ -389,6 +444,12 @@ function SubDirectoryItem(label, dirEntry, parentDirItem, tree) { |
item.__proto__ = SubDirectoryItem.prototype; |
item.entry = dirEntry; |
+ item.delayExpansion = parentDirItem.delayExpansion; |
+ |
+ if (item.delayExpansion) { |
+ item.clearHasChildren(); |
+ item.mayHaveChildren_ = true; |
+ } |
// Sets up icons of the item. |
var icon = item.querySelector('.icon'); |
@@ -461,6 +522,10 @@ function VolumeItem(modelItem, tree) { |
item.modelItem_ = modelItem; |
item.volumeInfo_ = modelItem.volumeInfo; |
+ // Provided volumes should delay the expansion of child nodes |
+ // for performance reasons. |
+ item.delayExpansion = (item.volumeInfo.volumeType === 'provided'); |
+ |
// Set helper attribute for testing. |
if (window.IN_TEST) |
item.setAttribute('volume-type-for-testing', item.volumeInfo_.volumeType); |