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 |