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

Side by Side Diff: chrome/browser/resources/file_manager/js/directory_model.js

Issue 12857002: Files.app: Add subfolders in the left nav (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 // If directory files changes too often, don't rescan directory more than once 5 // If directory files changes too often, don't rescan directory more than once
6 // per specified interval 6 // per specified interval
7 var SIMULTANEOUS_RESCAN_INTERVAL = 1000; 7 var SIMULTANEOUS_RESCAN_INTERVAL = 1000;
8 // Used for operations that require almost instant rescan. 8 // Used for operations that require almost instant rescan.
9 var SHORT_RESCAN_INTERVAL = 100; 9 var SHORT_RESCAN_INTERVAL = 100;
10 10
(...skipping 20 matching lines...) Expand all
31 this.rescanTime_ = null; 31 this.rescanTime_ = null;
32 this.scanFailures_ = 0; 32 this.scanFailures_ = 0;
33 this.driveEnabled_ = isDriveEnabled; 33 this.driveEnabled_ = isDriveEnabled;
34 34
35 this.currentFileListContext_ = new FileListContext( 35 this.currentFileListContext_ = new FileListContext(
36 metadataCache, fileList, false); 36 metadataCache, fileList, false);
37 this.currentDirContents_ = new DirectoryContentsBasic( 37 this.currentDirContents_ = new DirectoryContentsBasic(
38 this.currentFileListContext_, root); 38 this.currentFileListContext_, root);
39 39
40 this.rootsList_ = new cr.ui.ArrayDataModel([]); 40 this.rootsList_ = new cr.ui.ArrayDataModel([]);
41 this.rootsListSelection_ = new cr.ui.ListSingleSelectionModel();
42 this.rootsListSelection_.addEventListener(
43 'change', this.onRootChange_.bind(this));
44
45 this.rootsListSelection_.addEventListener(
46 'beforeChange', this.onBeforeRootChange_.bind(this));
47
48 /**
49 * A map root.fullPath -> currentDirectory.fullPath.
50 * @type {Object.<string, string>}
51 * @private
52 */
53 this.currentDirByRoot_ = {};
54 41
55 this.volumeManager_ = volumeManager; 42 this.volumeManager_ = volumeManager;
56 } 43 }
57 44
58 /** 45 /**
59 * Fake entry to be used in currentDirEntry_ when current directory is 46 * Fake entry to be used in currentDirEntry_ when current directory is
60 * unmounted DRIVE. 47 * unmounted DRIVE.
61 * @private 48 * @private
62 */ 49 */
63 DirectoryModel.fakeDriveEntry_ = { 50 DirectoryModel.fakeDriveEntry_ = {
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 }; 321 };
335 322
336 /** 323 /**
337 * @return {cr.ui.ArrayDataModel} The list of roots. 324 * @return {cr.ui.ArrayDataModel} The list of roots.
338 */ 325 */
339 DirectoryModel.prototype.getRootsList = function() { 326 DirectoryModel.prototype.getRootsList = function() {
340 return this.rootsList_; 327 return this.rootsList_;
341 }; 328 };
342 329
343 /** 330 /**
344 * @return {cr.ui.ListSingleSelectionModel} Root list selection model.
345 */
346 DirectoryModel.prototype.getRootsListSelectionModel = function() {
347 return this.rootsListSelection_;
348 };
349
350 /**
351 * Schedule rescan with short delay. 331 * Schedule rescan with short delay.
352 */ 332 */
353 DirectoryModel.prototype.rescanSoon = function() { 333 DirectoryModel.prototype.rescanSoon = function() {
354 this.scheduleRescan(SHORT_RESCAN_INTERVAL); 334 this.scheduleRescan(SHORT_RESCAN_INTERVAL);
355 }; 335 };
356 336
357 /** 337 /**
358 * Schedule rescan with delay. Designed to handle directory change 338 * Schedule rescan with delay. Designed to handle directory change
359 * notification. 339 * notification.
360 */ 340 */
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 if (path == '/') { 719 if (path == '/') {
740 successCallback(this.root_); 720 successCallback(this.root_);
741 return; 721 return;
742 } 722 }
743 723
744 this.root_.getDirectory(path, {create: false}, 724 this.root_.getDirectory(path, {create: false},
745 successCallback, errorCallback); 725 successCallback, errorCallback);
746 }; 726 };
747 727
748 /** 728 /**
749 * @return {Entry} Directory entry of the root selected in rootsList.
750 * @private
751 */
752 DirectoryModel.prototype.getSelectedRootDirEntry_ = function() {
753 return this.rootsList_.item(this.rootsListSelection_.selectedIndex);
754 };
755
756 /**
757 * Handler before root item change.
758 * @param {Event} event The event.
759 * @private
760 */
761 DirectoryModel.prototype.onBeforeRootChange_ = function(event) {
762 if (event.changes.length == 1 && !event.changes[0].selected)
763 event.preventDefault();
764 };
765
766 /**
767 * Handler for root item being clicked.
768 * @param {Event} event The event.
769 * @private
770 */
771 DirectoryModel.prototype.onRootChange_ = function(event) {
772 var newRootDir = this.getSelectedRootDirEntry_();
773 if (newRootDir)
774 this.changeRoot(newRootDir.fullPath);
775 };
776
777 /**
778 * Changes directory. If path points to a root (except current one)
779 * then directory changed to the last used one for the root.
780 *
781 * @param {string} path New current directory path or new root.
782 */
783 DirectoryModel.prototype.changeRoot = function(path) {
784 var currentDir = this.currentDirByRoot_[path] || path;
785 if (currentDir == this.getCurrentDirPath())
786 return;
787 var onError = path != currentDir && path != this.getCurrentDirPath() ?
788 this.changeDirectory.bind(this, path) : null;
789 this.resolveDirectory(
790 currentDir,
791 this.changeDirectoryEntry_.bind(this, false),
792 onError);
793 };
794
795 /**
796 * @param {DirectoryEntry} dirEntry The absolute path to the new directory. 729 * @param {DirectoryEntry} dirEntry The absolute path to the new directory.
797 * @param {function=} opt_callback Executed if the directory loads successfully. 730 * @param {function=} opt_callback Executed if the directory loads successfully.
798 * @private 731 * @private
799 */ 732 */
800 DirectoryModel.prototype.changeDirectoryEntrySilent_ = function(dirEntry, 733 DirectoryModel.prototype.changeDirectoryEntrySilent_ = function(dirEntry,
801 opt_callback) { 734 opt_callback) {
802 var onScanComplete = function() { 735 var onScanComplete = function() {
803 if (opt_callback) 736 if (opt_callback)
804 opt_callback(); 737 opt_callback();
805 // For tests that open the dialog to empty directories, everything 738 // For tests that open the dialog to empty directories, everything
806 // is loaded at this point. 739 // is loaded at this point.
807 chrome.test.sendMessage('directory-change-complete'); 740 chrome.test.sendMessage('directory-change-complete');
808 }; 741 };
809 this.clearAndScan_(new DirectoryContentsBasic(this.currentFileListContext_, 742 this.clearAndScan_(new DirectoryContentsBasic(this.currentFileListContext_,
810 dirEntry), 743 dirEntry),
811 onScanComplete.bind(this)); 744 onScanComplete.bind(this));
812 this.currentDirByRoot_[this.getCurrentRootPath()] = dirEntry.fullPath;
813 this.updateRootsListSelection_();
814 }; 745 };
815 746
816 /** 747 /**
817 * Change the current directory to the directory represented by a 748 * Change the current directory to the directory represented by a
818 * DirectoryEntry. 749 * DirectoryEntry.
819 * 750 *
820 * Dispatches the 'directory-changed' event when the directory is successfully 751 * Dispatches the 'directory-changed' event when the directory is successfully
821 * changed. 752 * changed.
822 * 753 *
823 * @param {boolean} initial True if it comes from setupPath and 754 * @param {boolean} initial True if it comes from setupPath and
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
1091 append.bind(this, 'archives')); 1022 append.bind(this, 'archives'));
1092 util.readDirectory(root, RootDirectory.REMOVABLE.substring(1), 1023 util.readDirectory(root, RootDirectory.REMOVABLE.substring(1),
1093 append.bind(this, 'removables')); 1024 append.bind(this, 'removables'));
1094 1025
1095 if (this.driveEnabled_) { 1026 if (this.driveEnabled_) {
1096 var fake = [DirectoryModel.fakeDriveEntry_]; 1027 var fake = [DirectoryModel.fakeDriveEntry_];
1097 if (this.isDriveMounted()) { 1028 if (this.isDriveMounted()) {
1098 readSingle(RootDirectory.DRIVE.substring(1), 'drive', fake); 1029 readSingle(RootDirectory.DRIVE.substring(1), 'drive', fake);
1099 } else { 1030 } else {
1100 groups.drive = fake; 1031 groups.drive = fake;
1032 done();
1101 } 1033 }
1102 // TODO(haruki): Add DirectoryModel.fakeDriveOfflineEntry_ to show the tab. 1034 // TODO(haruki): Add DirectoryModel.fakeDriveOfflineEntry_ to show the tab.
1103 } else { 1035 } else {
1104 groups.drive = []; 1036 groups.drive = [];
1037 done();
1105 } 1038 }
1106 }; 1039 };
1107 1040
1108 /** 1041 /**
1109 * Updates the roots list. 1042 * Updates the roots list.
1110 * @private 1043 * @private
1111 */ 1044 */
1112 DirectoryModel.prototype.updateRoots_ = function() { 1045 DirectoryModel.prototype.updateRoots_ = function() {
1113 var self = this; 1046 var self = this;
1114 this.resolveRoots_(function(rootEntries) { 1047 this.resolveRoots_(function(rootEntries) {
1115 var dm = self.rootsList_; 1048 var dm = self.rootsList_;
1116 var args = [0, dm.length].concat(rootEntries); 1049 var args = [0, dm.length].concat(rootEntries);
1117 dm.splice.apply(dm, args); 1050 dm.splice.apply(dm, args);
1118
1119 self.updateRootsListSelection_();
1120 }); 1051 });
1121 }; 1052 };
1122 1053
1123 /** 1054 /**
1124 * Find roots list item by root path.
1125 *
1126 * @param {string} path Root path.
1127 * @return {number} Index of the item.
1128 */
1129 DirectoryModel.prototype.findRootsListIndex = function(path) {
1130 var roots = this.rootsList_;
1131 for (var index = 0; index < roots.length; index++) {
1132 if (roots.item(index).fullPath == path)
1133 return index;
1134 }
1135 return -1;
1136 };
1137
1138 /**
1139 * @private
1140 */
1141 DirectoryModel.prototype.updateRootsListSelection_ = function() {
1142 var rootPath = this.getCurrentRootPath();
1143 this.rootsListSelection_.selectedIndex = this.findRootsListIndex(rootPath);
1144 };
1145
1146 /**
1147 * @return {boolean} True if DRIVE is fully mounted. 1055 * @return {boolean} True if DRIVE is fully mounted.
1148 */ 1056 */
1149 DirectoryModel.prototype.isDriveMounted = function() { 1057 DirectoryModel.prototype.isDriveMounted = function() {
1150 return this.volumeManager_.getDriveStatus() == 1058 return this.volumeManager_.getDriveStatus() ==
1151 VolumeManager.DriveStatus.MOUNTED; 1059 VolumeManager.DriveStatus.MOUNTED;
1152 }; 1060 };
1153 1061
1154 /** 1062 /**
1155 * Handler for the VolumeManager's 'change' event. 1063 * Handler for the VolumeManager's 'change' event.
1156 * @private 1064 * @private
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
1307 this.onClearSearch_ = onClearSearch; 1215 this.onClearSearch_ = onClearSearch;
1308 1216
1309 this.addEventListener('scan-completed', this.onSearchCompleted_); 1217 this.addEventListener('scan-completed', this.onSearchCompleted_);
1310 1218
1311 // If we are offline, let's fallback to file name search inside dir. 1219 // If we are offline, let's fallback to file name search inside dir.
1312 if (this.getCurrentRootType() === RootType.DRIVE && !this.isDriveOffline()) { 1220 if (this.getCurrentRootType() === RootType.DRIVE && !this.isDriveOffline()) {
1313 // Drive search is performed over the whole drive, so pass drive root as 1221 // Drive search is performed over the whole drive, so pass drive root as
1314 // |directoryEntry|. 1222 // |directoryEntry|.
1315 newDirContents = new DirectoryContentsDriveSearch( 1223 newDirContents = new DirectoryContentsDriveSearch(
1316 this.currentFileListContext_, 1224 this.currentFileListContext_,
1317 this.getSelectedRootDirEntry_(), 1225 this.getCurrentDirEntry(),
1318 this.currentDirContents_.getLastNonSearchDirectoryEntry(), 1226 this.currentDirContents_.getLastNonSearchDirectoryEntry(),
1319 query); 1227 query);
1320 } else { 1228 } else {
1321 newDirContents = new DirectoryContentsLocalSearch( 1229 newDirContents = new DirectoryContentsLocalSearch(
1322 this.currentFileListContext_, this.getCurrentDirEntry(), query); 1230 this.currentFileListContext_, this.getCurrentDirEntry(), query);
1323 } 1231 }
1324 this.clearAndScan_(newDirContents); 1232 this.clearAndScan_(newDirContents);
1325 }; 1233 };
1326 1234
1327 1235
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1504 }.bind(this)); 1412 }.bind(this));
1505 } 1413 }
1506 }; 1414 };
1507 1415
1508 /** 1416 /**
1509 * @return {DirectoryEntry} Current watched directory entry. 1417 * @return {DirectoryEntry} Current watched directory entry.
1510 */ 1418 */
1511 FileWatcher.prototype.getWatchedDirectoryEntry = function() { 1419 FileWatcher.prototype.getWatchedDirectoryEntry = function() {
1512 return this.watchedDirectoryEntry_; 1420 return this.watchedDirectoryEntry_;
1513 }; 1421 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698