Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: chrome/browser/resources/file_manager/foreground/js/directory_tree.js

Issue 135753003: Get rid of the fake Drive/root entry. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 'use strict'; 5 'use strict';
6 6
7 //////////////////////////////////////////////////////////////////////////////// 7 ////////////////////////////////////////////////////////////////////////////////
8 // DirectoryTreeUtil 8 // DirectoryTreeUtil
9 9
10 /** 10 /**
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 * @param {boolean} recursive True if the all visible sub-directories are 43 * @param {boolean} recursive True if the all visible sub-directories are
44 * updated recursively including left arrows. If false, the update walks 44 * updated recursively including left arrows. If false, the update walks
45 * only immediate child directories without arrows. 45 * only immediate child directories without arrows.
46 */ 46 */
47 DirectoryItemTreeBaseMethods.updateSubElementsFromList = function(recursive) { 47 DirectoryItemTreeBaseMethods.updateSubElementsFromList = function(recursive) {
48 var index = 0; 48 var index = 0;
49 var tree = this.parentTree_ || this; // If no parent, 'this' itself is tree. 49 var tree = this.parentTree_ || this; // If no parent, 'this' itself is tree.
50 while (this.entries_[index]) { 50 while (this.entries_[index]) {
51 var currentEntry = this.entries_[index]; 51 var currentEntry = this.entries_[index];
52 var currentElement = this.items[index]; 52 var currentElement = this.items[index];
53 // TODO(mtomasz): Stop using full paths, and use getLocationInfo() instead.
54 var label = PathUtil.getFolderLabel(currentEntry.fullPath);
53 55
54 if (index >= this.items.length) { 56 if (index >= this.items.length) {
55 var item = new DirectoryItem(currentEntry, this, tree); 57 var item = new DirectoryItem(label, currentEntry, this, tree);
56 this.add(item); 58 this.add(item);
57 index++; 59 index++;
58 } else if (currentEntry.fullPath == currentElement.fullPath) { 60 } else if (currentEntry.fullPath == currentElement.fullPath) {
59 if (recursive && this.expanded) 61 if (recursive && this.expanded)
60 currentElement.updateSubDirectories(true /* recursive */); 62 currentElement.updateSubDirectories(true /* recursive */);
61 63
62 index++; 64 index++;
63 } else if (currentEntry.fullPath < currentElement.fullPath) { 65 } else if (currentEntry.fullPath < currentElement.fullPath) {
64 var item = new DirectoryItem(currentEntry, this, tree); 66 var item = new DirectoryItem(label, currentEntry, this, tree);
65 this.addAt(item, index); 67 this.addAt(item, index);
66 index++; 68 index++;
67 } else if (currentEntry.fullPath > currentElement.fullPath) { 69 } else if (currentEntry.fullPath > currentElement.fullPath) {
68 this.remove(currentElement); 70 this.remove(currentElement);
69 } 71 }
70 } 72 }
71 73
72 var removedChild; 74 var removedChild;
73 while (removedChild = this.items[index]) { 75 while (removedChild = this.items[index]) {
74 this.remove(removedChild); 76 this.remove(removedChild);
(...skipping 27 matching lines...) Expand all
102 }; 104 };
103 105
104 Object.freeze(DirectoryItemTreeBaseMethods); 106 Object.freeze(DirectoryItemTreeBaseMethods);
105 107
106 //////////////////////////////////////////////////////////////////////////////// 108 ////////////////////////////////////////////////////////////////////////////////
107 // DirectoryItem 109 // DirectoryItem
108 110
109 /** 111 /**
110 * A directory in the tree. Each element represents one directory. 112 * A directory in the tree. Each element represents one directory.
111 * 113 *
114 * @param {string} label Label for this item.
112 * @param {DirectoryEntry} dirEntry DirectoryEntry of this item. 115 * @param {DirectoryEntry} dirEntry DirectoryEntry of this item.
113 * @param {DirectoryItem|DirectoryTree} parentDirItem Parent of this item. 116 * @param {DirectoryItem|DirectoryTree} parentDirItem Parent of this item.
114 * @param {DirectoryTree} tree Current tree, which contains this item. 117 * @param {DirectoryTree} tree Current tree, which contains this item.
115 * @extends {cr.ui.TreeItem} 118 * @extends {cr.ui.TreeItem}
116 * @constructor 119 * @constructor
117 */ 120 */
118 function DirectoryItem(dirEntry, parentDirItem, tree) { 121 function DirectoryItem(label, dirEntry, parentDirItem, tree) {
119 var item = cr.doc.createElement('div'); 122 var item = cr.doc.createElement('div');
120 DirectoryItem.decorate(item, dirEntry, parentDirItem, tree); 123 DirectoryItem.decorate(item, label, dirEntry, parentDirItem, tree);
121 return item; 124 return item;
122 } 125 }
123 126
124 /** 127 /**
125 * @param {HTMLElement} el Element to be DirectoryItem. 128 * @param {HTMLElement} el Element to be DirectoryItem.
129 * @param {string} label Label for this item.
126 * @param {DirectoryEntry} dirEntry DirectoryEntry of this item. 130 * @param {DirectoryEntry} dirEntry DirectoryEntry of this item.
127 * @param {DirectoryItem|DirectoryTree} parentDirItem Parent of this item. 131 * @param {DirectoryItem|DirectoryTree} parentDirItem Parent of this item.
128 * @param {DirectoryTree} tree Current tree, which contains this item. 132 * @param {DirectoryTree} tree Current tree, which contains this item.
129 */ 133 */
130 DirectoryItem.decorate = 134 DirectoryItem.decorate =
131 function(el, dirEntry, parentDirItem, tree) { 135 function(el, label, dirEntry, parentDirItem, tree) {
132 el.__proto__ = DirectoryItem.prototype; 136 el.__proto__ = DirectoryItem.prototype;
133 (/** @type {DirectoryItem} */ el).decorate( 137 (/** @type {DirectoryItem} */ el).decorate(
134 dirEntry, parentDirItem, tree); 138 label, dirEntry, parentDirItem, tree);
135 }; 139 };
136 140
137 DirectoryItem.prototype = { 141 DirectoryItem.prototype = {
138 __proto__: cr.ui.TreeItem.prototype, 142 __proto__: cr.ui.TreeItem.prototype,
139 143
140 /** 144 /**
141 * The DirectoryEntry corresponding to this DirectoryItem. This may be 145 * The DirectoryEntry corresponding to this DirectoryItem. This may be
142 * a dummy DirectoryEntry. 146 * a dummy DirectoryEntry.
143 * @type {DirectoryEntry|Object} 147 * @type {DirectoryEntry|Object}
144 */ 148 */
(...skipping 26 matching lines...) Expand all
171 * Calls DirectoryItemTreeBaseMethods.updateSubElementsFromList(). 175 * Calls DirectoryItemTreeBaseMethods.updateSubElementsFromList().
172 * @param {DirectoryEntry|Object} entry The entry to be searched for. Can be 176 * @param {DirectoryEntry|Object} entry The entry to be searched for. Can be
173 * a fake. 177 * a fake.
174 * @return {boolean} True if the parent item is found. 178 * @return {boolean} True if the parent item is found.
175 */ 179 */
176 DirectoryItem.prototype.searchAndSelectByEntry = function(entry) { 180 DirectoryItem.prototype.searchAndSelectByEntry = function(entry) {
177 return DirectoryItemTreeBaseMethods.searchAndSelectByEntry.call(this, entry); 181 return DirectoryItemTreeBaseMethods.searchAndSelectByEntry.call(this, entry);
178 }; 182 };
179 183
180 /** 184 /**
185 * @param {string} label Localized label for this item.
181 * @param {DirectoryEntry} dirEntry DirectoryEntry of this item. 186 * @param {DirectoryEntry} dirEntry DirectoryEntry of this item.
182 * @param {DirectoryItem|DirectoryTree} parentDirItem Parent of this item. 187 * @param {DirectoryItem|DirectoryTree} parentDirItem Parent of this item.
183 * @param {DirectoryTree} tree Current tree, which contains this item. 188 * @param {DirectoryTree} tree Current tree, which contains this item.
184 */ 189 */
185 DirectoryItem.prototype.decorate = function( 190 DirectoryItem.prototype.decorate = function(
186 dirEntry, parentDirItem, tree) { 191 label, dirEntry, parentDirItem, tree) {
187 this.className = 'tree-item'; 192 this.className = 'tree-item';
188 this.innerHTML = 193 this.innerHTML =
189 '<div class="tree-row">' + 194 '<div class="tree-row">' +
190 ' <span class="expand-icon"></span>' + 195 ' <span class="expand-icon"></span>' +
191 ' <span class="icon"></span>' + 196 ' <span class="icon"></span>' +
192 ' <span class="label"></span>' + 197 ' <span class="label"></span>' +
193 '</div>' + 198 '</div>' +
194 '<div class="tree-children"></div>'; 199 '<div class="tree-children"></div>';
195 this.setAttribute('role', 'treeitem'); 200 this.setAttribute('role', 'treeitem');
196 201
197 this.parentTree_ = tree; 202 this.parentTree_ = tree;
198 this.directoryModel_ = tree.directoryModel; 203 this.directoryModel_ = tree.directoryModel;
199 this.parent_ = parentDirItem; 204 this.parent_ = parentDirItem;
200 this.label = dirEntry.label || dirEntry.name; 205 this.label = label;
201 this.fullPath = dirEntry.fullPath; 206 this.fullPath = dirEntry.fullPath;
202 this.dirEntry_ = dirEntry; 207 this.dirEntry_ = dirEntry;
203 this.fileFilter_ = this.directoryModel_.getFileFilter(); 208 this.fileFilter_ = this.directoryModel_.getFileFilter();
204 209
205 // Sets hasChildren=false tentatively. This will be overridden after 210 // Sets hasChildren=false tentatively. This will be overridden after
206 // scanning sub-directories in DirectoryTreeUtil.updateSubElementsFromList. 211 // scanning sub-directories in DirectoryTreeUtil.updateSubElementsFromList.
207 this.hasChildren = false; 212 this.hasChildren = false;
208 213
209 this.addEventListener('expand', this.onExpand_.bind(this), false); 214 this.addEventListener('expand', this.onExpand_.bind(this), false);
210 var icon = this.querySelector('.icon'); 215 var icon = this.querySelector('.icon');
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 } 509 }
505 }.bind(this)); 510 }.bind(this));
506 511
507 this.privateOnDirectoryChangedBound_ = 512 this.privateOnDirectoryChangedBound_ =
508 this.onDirectoryContentChanged_.bind(this); 513 this.onDirectoryContentChanged_.bind(this);
509 chrome.fileBrowserPrivate.onDirectoryChanged.addListener( 514 chrome.fileBrowserPrivate.onDirectoryChanged.addListener(
510 this.privateOnDirectoryChangedBound_); 515 this.privateOnDirectoryChangedBound_);
511 516
512 this.scrollBar_ = MainPanelScrollBar(); 517 this.scrollBar_ = MainPanelScrollBar();
513 this.scrollBar_.initialize(this.parentNode, this); 518 this.scrollBar_.initialize(this.parentNode, this);
514
515 // Once, draws the list with the fake '/drive/' entry.
516 this.redraw(false /* recursive */);
517 // Resolves 'My Drive' entry and replaces the fake with the true one.
518 this.maybeResolveMyDriveRoot_(function() {
519 // After the true entry is resolved, draws the list again.
520 this.redraw(true /* recursive */);
521 }.bind(this));
522 }; 519 };
523 520
524 /** 521 /**
525 * Select the item corresponding to the given entry. 522 * Select the item corresponding to the given entry.
526 * @param {DirectoryEntry|Object} entry The directory entry to be selected. Can 523 * @param {DirectoryEntry|Object} entry The directory entry to be selected. Can
527 * be a fake. 524 * be a fake.
528 */ 525 */
529 DirectoryTree.prototype.selectByEntry = function(entry) { 526 DirectoryTree.prototype.selectByEntry = function(entry) {
530 // If the target directory is not in the tree, do nothing. 527 // If the target directory is not in the tree, do nothing.
531 if (!DirectoryTreeUtil.isEligiblePathForDirectoryTree(entry.fullPath)) 528 if (!DirectoryTreeUtil.isEligiblePathForDirectoryTree(entry.fullPath))
532 return; 529 return;
533 530
534 this.maybeResolveMyDriveRoot_(function() { 531 var volumeInfo = this.volumeManager_.getVolumeInfo(entry);
535 if (this.selectedItem && util.isSameEntry(entry, this.selectedItem.entry)) 532 if (this.selectedItem && util.isSameEntry(entry, this.selectedItem.entry))
536 return; 533 return;
537 534
538 if (this.searchAndSelectByEntry(entry)) 535 if (this.searchAndSelectByEntry(entry))
539 return; 536 return;
540 537
541 this.selectedItem = null; 538 this.updateSubDirectories(false /* recursive */);
542 this.updateSubDirectories( 539 // TODO(yoshiki, mtomasz): There may be a race in here.
543 false /* recursive */, 540 volumeInfo.resolveDisplayRoot(function() {
544 // Success callback, failure is not handled. 541 if (!this.searchAndSelectByEntry(entry))
545 function() { 542 this.selectedItem = null;
546 if (!this.searchAndSelectByEntry(entry))
547 this.selectedItem = null;
548 }.bind(this));
549 }.bind(this)); 543 }.bind(this));
550 }; 544 };
551 545
552 /** 546 /**
553 * Resolves the My Drive root's entry, if it is a fake. If the entry is already 547 * Retrieves the latest subdirectories and update them on the tree.
554 * resolved to a DirectoryEntry, completionCallback() will be called 548 *
555 * immediately. 549 * @param {boolean} recursive True if the update is recursively.
556 * @param {function()} completionCallback Called when the resolving is 550 * @param {function()=} opt_callback Called when subdirectories are fully
557 * done (or the entry is already resolved), regardless if it is 551 * updated.
558 * successfully done or not.
559 * @private
560 */ 552 */
561 DirectoryTree.prototype.maybeResolveMyDriveRoot_ = function( 553 DirectoryTree.prototype.updateSubDirectories = function(
yoshiki 2014/01/15 07:33:13 Could you change the method name? Or change the na
mtomasz 2014/01/16 01:31:58 There is no defined interface @interface, not this
yoshiki 2014/01/17 01:57:52 OK. I agree with you.
562 completionCallback) { 554 recursive, opt_callback) {
563 var myDriveItem = this.items[0]; 555 var callback = opt_callback || function() {};
564 if (!myDriveItem || !util.isFakeEntry(myDriveItem.entry)) { 556 this.entries_ = [];
565 // The entry is already resolved. Don't need to try again. 557
566 completionCallback(); 558 var compareEntries = function(a, b) {
567 return; 559 return a.toURL() < b.toURL();
560 };
561
562 // Add fakes (if any).
563 for (var key in this.currentVolumeInfo_.fakeEntries) {
564 this.entries_.push(this.currentVolumeInfo_.fakeEntries[key]);
568 } 565 }
569 566
570 // The entry is a fake. 567 // If the display root is not available yet, then redraw anyway with what
571 this.directoryModel_.resolveDirectory( 568 // we have. However, concurrently try to resolve the display root and then
572 myDriveItem.fullPath, 569 // redraw.
573 function(entry) { 570 if (!this.currentVolumeInfo_.displayRoot) {
574 if (!util.isFakeEntry(entry)) 571 this.entries_.sort(compareEntries);
575 myDriveItem.dirEntry_ = entry; 572 this.redraw(recursive);
573 }
576 574
577 completionCallback(); 575 this.currentVolumeInfo_.resolveDisplayRoot(function(displayRoot) {
578 }, 576 this.entries_.push(this.currentVolumeInfo_.displayRoot);
579 completionCallback); 577 this.entries_.sort(compareEntries);
578 this.redraw(recursive); // Redraw.
579 callback();
580 }.bind(this), callback /* Ignore errors. */);
580 }; 581 };
581 582
582 /** 583 /**
583 * Retrieves the latest subdirectories and update them on the tree.
584 * @param {boolean} recursive True if the update is recursively.
585 * @param {function()=} opt_successCallback Callback called on success.
586 * @param {function()=} opt_errorCallback Callback called on error.
587 */
588 DirectoryTree.prototype.updateSubDirectories = function(
589 recursive, opt_successCallback, opt_errorCallback) {
590 var hasFakeEntries = this.currentVolumeInfo_ &&
591 this.currentVolumeInfo_.volumeType === util.VolumeType.DRIVE;
592 this.entries_ = hasFakeEntries ? [
593 this.currentVolumeInfo_.fakeEntries[RootType.DRIVE],
594 this.currentVolumeInfo_.fakeEntries[RootType.DRIVE_OFFLINE],
595 this.currentVolumeInfo_.fakeEntries[RootType.DRIVE_SHARED_WITH_ME],
596 this.currentVolumeInfo_.fakeEntries[RootType.DRIVE_RECENT]
597 ] : [];
598
599 this.redraw(recursive);
600 if (opt_successCallback)
601 opt_successCallback();
602 };
603
604 /**
605 * Redraw the list. 584 * Redraw the list.
606 * @param {boolean} recursive True if the update is recursively. False if the 585 * @param {boolean} recursive True if the update is recursively. False if the
607 * only root items are updated. 586 * only root items are updated.
608 */ 587 */
609 DirectoryTree.prototype.redraw = function(recursive) { 588 DirectoryTree.prototype.redraw = function(recursive) {
610 this.updateSubElementsFromList(recursive); 589 this.updateSubElementsFromList(recursive);
611 }; 590 };
612 591
613 /** 592 /**
614 * Invoked when the filter is changed. 593 * Invoked when the filter is changed.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 this.style.paddingBottom = margin + 'px'; 639 this.style.paddingBottom = margin + 'px';
661 this.scrollBar_.setBottomMarginForPanel(margin); 640 this.scrollBar_.setBottomMarginForPanel(margin);
662 }; 641 };
663 642
664 /** 643 /**
665 * Updates the UI after the layout has changed. 644 * Updates the UI after the layout has changed.
666 */ 645 */
667 DirectoryTree.prototype.relayout = function() { 646 DirectoryTree.prototype.relayout = function() {
668 cr.dispatchSimpleEvent(this, 'relayout'); 647 cr.dispatchSimpleEvent(this, 'relayout');
669 }; 648 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698