| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 }; |
| OLD | NEW |