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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
50 | 50 |
51 // The map 'name' -> callback. Callbacks are function(entry) -> boolean. | 51 // The map 'name' -> callback. Callbacks are function(entry) -> boolean. |
52 this.filters_ = {}; | 52 this.filters_ = {}; |
53 this.setFilterHidden(true); | 53 this.setFilterHidden(true); |
54 | 54 |
55 /** | 55 /** |
56 * @private | 56 * @private |
57 * @type {Object.<string, boolean>} | 57 * @type {Object.<string, boolean>} |
58 */ | 58 */ |
59 this.volumeReadOnlyStatus_ = {}; | 59 this.volumeReadOnlyStatus_ = {}; |
60 | |
61 /** | |
62 * File path of the last directory that is not under virtual search directory. | |
63 * This is the path to go to when the search box content clears on GData. | |
64 * @private | |
65 * @type {string} | |
66 */ | |
67 this.lastNonGDataSearchDirPath_ = null; | |
60 } | 68 } |
61 | 69 |
62 /** | 70 /** |
63 * The name of the directory containing externally | 71 * The name of the directory containing externally |
64 * mounted removable storage volumes. | 72 * mounted removable storage volumes. |
65 */ | 73 */ |
66 DirectoryModel.REMOVABLE_DIRECTORY = 'removable'; | 74 DirectoryModel.REMOVABLE_DIRECTORY = 'removable'; |
67 | 75 |
68 /** | 76 /** |
69 * The name of the directory containing externally | 77 * The name of the directory containing externally |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
172 * @return {boolean} If current directory is system. | 180 * @return {boolean} If current directory is system. |
173 */ | 181 */ |
174 DirectoryModel.prototype.isSystemDirectory = function() { | 182 DirectoryModel.prototype.isSystemDirectory = function() { |
175 var path = this.currentDirEntry_.fullPath; | 183 var path = this.currentDirEntry_.fullPath; |
176 return path == '/' || | 184 return path == '/' || |
177 path == '/' + DirectoryModel.REMOVABLE_DIRECTORY || | 185 path == '/' + DirectoryModel.REMOVABLE_DIRECTORY || |
178 path == '/' + DirectoryModel.ARCHIVE_DIRECTORY; | 186 path == '/' + DirectoryModel.ARCHIVE_DIRECTORY; |
179 }; | 187 }; |
180 | 188 |
181 /** | 189 /** |
190 * Tests if the entry is a gdata search result entry. | |
191 * @param {entry} entry Entry to test. | |
192 * @return {boolean} Result. | |
193 */ | |
194 DirectoryModel.prototype.isGDataSearchResult = function(entry) { | |
195 return (util.getFileAndDisplayNameForGDataSearchResult(entry.fullPath) != | |
196 null); | |
197 }; | |
198 | |
199 /** | |
182 * @return {boolean} If the files with names starting with "." are not shown. | 200 * @return {boolean} If the files with names starting with "." are not shown. |
183 */ | 201 */ |
184 DirectoryModel.prototype.isFilterHiddenOn = function() { | 202 DirectoryModel.prototype.isFilterHiddenOn = function() { |
185 return !!this.filters_['hidden']; | 203 return !!this.filters_['hidden']; |
186 }; | 204 }; |
187 | 205 |
188 /** | 206 /** |
189 * @param {boolean} value Whether files with leading "." are hidden. | 207 * @param {boolean} value Whether files with leading "." are hidden. |
190 */ | 208 */ |
191 DirectoryModel.prototype.setFilterHidden = function(value) { | 209 DirectoryModel.prototype.setFilterHidden = function(value) { |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
490 callback) { | 508 callback) { |
491 var field = this.fileList_.sortStatus.field; | 509 var field = this.fileList_.sortStatus.field; |
492 if (field) { | 510 if (field) { |
493 this.prepareSortEntries_(entries, field, callback); | 511 this.prepareSortEntries_(entries, field, callback); |
494 } else { | 512 } else { |
495 callback(); | 513 callback(); |
496 } | 514 } |
497 }; | 515 }; |
498 | 516 |
499 /** | 517 /** |
518 * Gets name that should be dispalyed in the UI for the entry. | |
519 * @param {string} path Full path of the entry whose display name we are | |
520 * getting. | |
521 * @param {string} defaultName Default name to use if no name is calculated. | |
522 * @return {string} Name to be used for display. | |
523 */ | |
524 DirectoryModel.prototype.getDisplayName = function(path, defaultName) { | |
525 var searchResultName = util.getFileAndDisplayNameForGDataSearchResult(path); | |
526 return searchResultName ? searchResultName.displayName : defaultName; | |
527 }; | |
528 | |
529 /** | |
500 * Delete the list of files and directories from filesystem and | 530 * Delete the list of files and directories from filesystem and |
501 * update the file list. | 531 * update the file list. |
502 * @param {Array.<Entry>} entries Entries to delete. | 532 * @param {Array.<Entry>} entries Entries to delete. |
503 * @param {function()=} opt_callback Called when finished. | 533 * @param {function()=} opt_callback Called when finished. |
504 */ | 534 */ |
505 DirectoryModel.prototype.deleteEntries = function(entries, opt_callback) { | 535 DirectoryModel.prototype.deleteEntries = function(entries, opt_callback) { |
506 var downcount = entries.length + 1; | 536 var downcount = entries.length + 1; |
507 | 537 |
508 var onComplete = opt_callback ? function() { | 538 var onComplete = opt_callback ? function() { |
509 if (--downcount == 0) | 539 if (--downcount == 0) |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
590 */ | 620 */ |
591 DirectoryModel.prototype.renameEntry = function(entry, newName, errorCallback, | 621 DirectoryModel.prototype.renameEntry = function(entry, newName, errorCallback, |
592 opt_successCallback) { | 622 opt_successCallback) { |
593 var self = this; | 623 var self = this; |
594 function onSuccess(newEntry) { | 624 function onSuccess(newEntry) { |
595 self.prefetchCacheForSorting_([newEntry], function() { | 625 self.prefetchCacheForSorting_([newEntry], function() { |
596 var fileList = self.fileList_; | 626 var fileList = self.fileList_; |
597 var index = fileList.indexOf(entry); | 627 var index = fileList.indexOf(entry); |
598 if (index >= 0) | 628 if (index >= 0) |
599 fileList.splice(index, 1, newEntry); | 629 fileList.splice(index, 1, newEntry); |
600 self.selectEntry(newName); | 630 self.selectEntry(newEntry.name); |
601 // If the entry doesn't exist in the list it mean that it updated from | 631 // If the entry doesn't exist in the list it mean that it updated from |
602 // outside (probably by directory rescan). | 632 // outside (probably by directory rescan). |
603 if (opt_successCallback) | 633 if (opt_successCallback) |
604 opt_successCallback(); | 634 opt_successCallback(); |
605 }); | 635 }); |
606 } | 636 } |
607 entry.moveTo(this.currentDirEntry_, newName, onSuccess, errorCallback); | 637 |
638 // If we are renaming gdata search result, we'll have to format newName to | |
639 // use in file system operation like: <resource_id>.<file_name>. | |
640 var searchResultName = | |
641 util.getFileAndDisplayNameForGDataSearchResult(entry.fullPath); | |
642 var newNameToUse = | |
643 searchResultName ? searchResultName.resourceId + '.' + newName : newName; | |
644 | |
645 entry.moveTo(this.currentDirEntry_, newNameToUse, onSuccess, errorCallback); | |
608 }; | 646 }; |
609 | 647 |
610 /** | 648 /** |
611 * Checks if current directory contains a file or directory with this name. | 649 * Checks if current directory contains a file or directory with this name. |
650 * @param {string} entry Entry to which newNAme will be given. | |
612 * @param {string} newName Name to check. | 651 * @param {string} newName Name to check. |
613 * @param {function(boolean, boolean?)} callback Called when the result's | 652 * @param {function(boolean, boolean?)} callback Called when the result's |
614 * available. First parameter is true if the entry exists and second | 653 * available. First parameter is true if the entry exists and second |
615 * is true if it's a file. | 654 * is true if it's a file. |
616 */ | 655 */ |
617 DirectoryModel.prototype.doesExist = function(newName, callback) { | 656 DirectoryModel.prototype.doesExist = function(entry, newName, callback) { |
618 util.resolvePath(this.currentDirEntry_, newName, | 657 // If we are looking for gdata search result, we'll have to format newName to |
658 // use in file system operation like: <resource_id>.<file_name>. | |
659 var searchResultName = | |
660 util.getFileAndDisplayNameForGDataSearchResult(entry.fullPath); | |
661 var newNameToUse = | |
662 searchResultName ? searchResultName.resourceId + '.' + newName : newName; | |
SeRya
2012/05/07 14:06:00
Code duplication. Create a method.
tbarzic
2012/05/10 03:20:47
Done.
| |
663 | |
664 util.resolvePath(this.currentDirEntry_, newNameToUse, | |
619 function(entry) { | 665 function(entry) { |
620 callback(true, entry.isFile); | 666 callback(true, entry.isFile); |
621 }, | 667 }, |
622 callback.bind(window, false)); | 668 callback.bind(window, false)); |
623 }; | 669 }; |
624 | 670 |
625 /** | 671 /** |
626 * Creates directory and updates the file list. | 672 * Creates directory and updates the file list. |
627 * | 673 * |
628 * @param {string} name Directory name. | 674 * @param {string} name Directory name. |
(...skipping 30 matching lines...) Expand all Loading... | |
659 * Changes directory. Causes 'directory-change' event. | 705 * Changes directory. Causes 'directory-change' event. |
660 * | 706 * |
661 * @param {string} path New current directory path. | 707 * @param {string} path New current directory path. |
662 */ | 708 */ |
663 DirectoryModel.prototype.changeDirectory = function(path) { | 709 DirectoryModel.prototype.changeDirectory = function(path) { |
664 this.resolveDirectory(path, function(directoryEntry) { | 710 this.resolveDirectory(path, function(directoryEntry) { |
665 this.changeDirectoryEntry_(false, directoryEntry); | 711 this.changeDirectoryEntry_(false, directoryEntry); |
666 }.bind(this), function(error) { | 712 }.bind(this), function(error) { |
667 console.error('Error changing directory to ' + path + ': ', error); | 713 console.error('Error changing directory to ' + path + ': ', error); |
668 }); | 714 }); |
669 } | 715 }; |
670 | 716 |
671 /** | 717 /** |
672 * Resolves absolute directory path. Handles GData stub. | 718 * Resolves absolute directory path. Handles GData stub. |
673 * @param {string} path Path to the directory. | 719 * @param {string} path Path to the directory. |
674 * @param {function(DirectoryEntry} successCallback Success callback. | 720 * @param {function(DirectoryEntry} successCallback Success callback. |
675 * @param {function(FileError} errorCallback Error callback. | 721 * @param {function(FileError} errorCallback Error callback. |
676 */ | 722 */ |
677 DirectoryModel.prototype.resolveDirectory = function(path, successCallback, | 723 DirectoryModel.prototype.resolveDirectory = function(path, successCallback, |
678 errorCallback) { | 724 errorCallback) { |
679 if (this.unmountedGDataEntry_ && | 725 if (this.unmountedGDataEntry_ && |
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1106 // Re-place the entry into the roots data model to force re-rendering. | 1152 // Re-place the entry into the roots data model to force re-rendering. |
1107 this.rootsList_.splice(index, 1, entry); | 1153 this.rootsList_.splice(index, 1, entry); |
1108 | 1154 |
1109 if (rootPath == this.rootPath) { | 1155 if (rootPath == this.rootPath) { |
1110 // TODO(kaznacheev): Consider changing to the most recently used root. | 1156 // TODO(kaznacheev): Consider changing to the most recently used root. |
1111 this.changeDirectory(this.getDefaultDirectory()); | 1157 this.changeDirectory(this.getDefaultDirectory()); |
1112 } | 1158 } |
1113 }; | 1159 }; |
1114 | 1160 |
1115 /** | 1161 /** |
1162 * Performs search and displays results. The search type is dependent on the | |
1163 * current directory. If we are currently on gdata, server side content search | |
1164 * over gdata mount point. If the current directory is not on the gdata, file | |
1165 * name search over current directory wil be performed. | |
1166 * | |
1167 * @param {string} query Query that will be searched for. | |
1168 */ | |
1169 DirectoryModel.prototype.search = function(query) { | |
1170 if (this.getCurrentRootPath() == '/' + DirectoryModel.GDATA_DIRECTORY) { | |
1171 if (query) { | |
1172 var currentDirPath = this.currentDirEntry_.fullPath; | |
1173 if (currentDirPath.search(util.GDATA_SEARCH_ROOT_PATH) != 0) | |
1174 this.lastNonGDataSearchDirPath_ = currentDirPath; | |
1175 this.changeDirectory(util.createGDataSearchPath(query)); | |
1176 } else { | |
1177 var newDirPath = this.lastNonGDataSearchDirPath_ || | |
1178 '/' + DirectoryModel.GDATA_DIRECTORY; | |
1179 this.lastNonGDataSearchDirPath_; | |
SeRya
2012/05/07 14:06:00
As I mentioned before I don't think that changing
tbarzic
2012/05/10 03:20:47
Yep, this is much cleaner, thanks for suggestion ;
| |
1180 this.changeDirectory(newDirPath); | |
1181 } | |
1182 } else { | |
1183 if (query) { | |
1184 this.addFilter( | |
1185 'searchbox', | |
1186 function(e) { | |
1187 return e.name.substring(0, query.length) == query; | |
1188 }); | |
1189 } else { | |
1190 this.directoryModel_.removeFilter('searchbox'); | |
1191 } | |
1192 } | |
1193 }; | |
1194 | |
1195 /** | |
1116 * @param {string} path Any path. | 1196 * @param {string} path Any path. |
1117 * @return {string} The root path. | 1197 * @return {string} The root path. |
1118 */ | 1198 */ |
1119 DirectoryModel.getRootPath = function(path) { | 1199 DirectoryModel.getRootPath = function(path) { |
1120 var type = DirectoryModel.getRootType(path); | 1200 var type = DirectoryModel.getRootType(path); |
1121 | 1201 |
1122 if (type == DirectoryModel.RootType.DOWNLOADS) | 1202 if (type == DirectoryModel.RootType.DOWNLOADS) |
1123 return '/' + DirectoryModel.DOWNLOADS_DIRECTORY; | 1203 return '/' + DirectoryModel.DOWNLOADS_DIRECTORY; |
1124 if (type == DirectoryModel.RootType.GDATA) | 1204 if (type == DirectoryModel.RootType.GDATA) |
1125 return '/' + DirectoryModel.GDATA_DIRECTORY; | 1205 return '/' + DirectoryModel.GDATA_DIRECTORY; |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1266 /** | 1346 /** |
1267 * @private | 1347 * @private |
1268 */ | 1348 */ |
1269 DirectoryModel.Scanner.prototype.recordMetrics_ = function() { | 1349 DirectoryModel.Scanner.prototype.recordMetrics_ = function() { |
1270 metrics.recordInterval('DirectoryScan'); | 1350 metrics.recordInterval('DirectoryScan'); |
1271 if (this.dir_.fullPath == | 1351 if (this.dir_.fullPath == |
1272 '/' + DirectoryModel.DOWNLOADS_DIRECTORY) { | 1352 '/' + DirectoryModel.DOWNLOADS_DIRECTORY) { |
1273 metrics.recordMediumCount('DownloadsCount', this.list_.length); | 1353 metrics.recordMediumCount('DownloadsCount', this.list_.length); |
1274 } | 1354 } |
1275 }; | 1355 }; |
OLD | NEW |