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

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

Issue 10342010: Add gdata content search to file_manager (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 7 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
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.lastNonGDataSearchDir_ = 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 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 callback) { 498 callback) {
491 var field = this.fileList_.sortStatus.field; 499 var field = this.fileList_.sortStatus.field;
492 if (field) { 500 if (field) {
493 this.prepareSortEntries_(entries, field, callback); 501 this.prepareSortEntries_(entries, field, callback);
494 } else { 502 } else {
495 callback(); 503 callback();
496 } 504 }
497 }; 505 };
498 506
499 /** 507 /**
508 * Gets name that should be dispalyed in the UI for the entry.
509 * @param {string} path Full path of the entry whose display name we are
510 * getting.
511 * @param {string} defaultName Default name to use if no name is calculated.
512 * @return {string} Name to be used for display.
513 */
514 DirectoryModel.prototype.getDisplayName = function(path, defaultName) {
515 var searchResultName = util.getFileAndDisplayNameForGDataSearchResult(path);
516 return searchResultName ? searchResultName.displayName : defaultName;
517 };
518
519 /**
500 * Delete the list of files and directories from filesystem and 520 * Delete the list of files and directories from filesystem and
501 * update the file list. 521 * update the file list.
502 * @param {Array.<Entry>} entries Entries to delete. 522 * @param {Array.<Entry>} entries Entries to delete.
503 * @param {function()=} opt_callback Called when finished. 523 * @param {function()=} opt_callback Called when finished.
504 */ 524 */
505 DirectoryModel.prototype.deleteEntries = function(entries, opt_callback) { 525 DirectoryModel.prototype.deleteEntries = function(entries, opt_callback) {
506 var downcount = entries.length + 1; 526 var downcount = entries.length + 1;
507 527
508 var onComplete = opt_callback ? function() { 528 var onComplete = opt_callback ? function() {
509 if (--downcount == 0) 529 if (--downcount == 0)
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 */ 610 */
591 DirectoryModel.prototype.renameEntry = function(entry, newName, errorCallback, 611 DirectoryModel.prototype.renameEntry = function(entry, newName, errorCallback,
592 opt_successCallback) { 612 opt_successCallback) {
593 var self = this; 613 var self = this;
594 function onSuccess(newEntry) { 614 function onSuccess(newEntry) {
595 self.prefetchCacheForSorting_([newEntry], function() { 615 self.prefetchCacheForSorting_([newEntry], function() {
596 var fileList = self.fileList_; 616 var fileList = self.fileList_;
597 var index = fileList.indexOf(entry); 617 var index = fileList.indexOf(entry);
598 if (index >= 0) 618 if (index >= 0)
599 fileList.splice(index, 1, newEntry); 619 fileList.splice(index, 1, newEntry);
600 self.selectEntry(newName); 620 self.selectEntry(newEntry.name);
601 // If the entry doesn't exist in the list it mean that it updated from 621 // If the entry doesn't exist in the list it mean that it updated from
602 // outside (probably by directory rescan). 622 // outside (probably by directory rescan).
603 if (opt_successCallback) 623 if (opt_successCallback)
604 opt_successCallback(); 624 opt_successCallback();
605 }); 625 });
606 } 626 }
607 entry.moveTo(this.currentDirEntry_, newName, onSuccess, errorCallback); 627
628 var newNameToUse = this.getNameToUseInRenaming_(entry, newName);
629 entry.moveTo(this.currentDirEntry_, newNameToUse, onSuccess, errorCallback);
608 }; 630 };
609 631
610 /** 632 /**
611 * Checks if current directory contains a file or directory with this name. 633 * Checks if current directory contains a file or directory with this name.
634 * @param {string} entry Entry to which newName will be given.
612 * @param {string} newName Name to check. 635 * @param {string} newName Name to check.
613 * @param {function(boolean, boolean?)} callback Called when the result's 636 * @param {function(boolean, boolean?)} callback Called when the result's
614 * available. First parameter is true if the entry exists and second 637 * available. First parameter is true if the entry exists and second
615 * is true if it's a file. 638 * is true if it's a file.
616 */ 639 */
617 DirectoryModel.prototype.doesExist = function(newName, callback) { 640 DirectoryModel.prototype.doesExist = function(entry, newName, callback) {
SeRya 2012/05/10 08:44:16 May be rename newName to newDisplayName (here and
tbarzic 2012/05/10 23:28:02 Done.
618 util.resolvePath(this.currentDirEntry_, newName, 641 var newNameToUse = this.getNameToUseInRenaming_(entry, newName);
642
643 util.resolvePath(this.currentDirEntry_, newNameToUse,
619 function(entry) { 644 function(entry) {
620 callback(true, entry.isFile); 645 callback(true, entry.isFile);
621 }, 646 },
622 callback.bind(window, false)); 647 callback.bind(window, false));
623 }; 648 };
624 649
625 /** 650 /**
651 * Creates file name that should be used as a new file name in filesystem
652 * operations while renaming. It the given entry is not a gdata search result
653 * entry, |newName| will be used.
654 *
655 * @private
656 * @param {Entry} entry Entry which is being renamed.
657 * @param {string} newName The new file name provided by user.
658 * @return {string} File name that should be used in renaming filesystem
659 * operations.
660 */
661 DirectoryModel.prototype.getNameToUseInRenaming_ = function(entry, newName) {
SeRya 2012/05/10 08:44:16 This method effectively is opposite to getDisplayN
tbarzic 2012/05/10 23:28:02 Done.
662 // If we are renaming gdata search result, we'll have to format newName to
663 // use in file system operation like: <resource_id>.<file_name>.
664 var searchResultName =
665 util.getFileAndDisplayNameForGDataSearchResult(entry.fullPath);
666 return searchResultName ? searchResultName.resourceId + '.' + newName :
667 newName;
668 };
669
670 /**
626 * Creates directory and updates the file list. 671 * Creates directory and updates the file list.
627 * 672 *
628 * @param {string} name Directory name. 673 * @param {string} name Directory name.
629 * @param {function} successCallback Callback on success. 674 * @param {function} successCallback Callback on success.
630 * @param {function} errorCallback Callback on failure. 675 * @param {function} errorCallback Callback on failure.
631 */ 676 */
632 DirectoryModel.prototype.createDirectory = function(name, successCallback, 677 DirectoryModel.prototype.createDirectory = function(name, successCallback,
633 errorCallback) { 678 errorCallback) {
634 var self = this; 679 var self = this;
635 function onSuccess(newEntry) { 680 function onSuccess(newEntry) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 * changed. 769 * changed.
725 * 770 *
726 * @private 771 * @private
727 * @param {boolean} initial True if it comes from setupPath and 772 * @param {boolean} initial True if it comes from setupPath and
728 * false if caused by an user action. 773 * false if caused by an user action.
729 * @param {DirectoryEntry} dirEntry The absolute path to the new directory. 774 * @param {DirectoryEntry} dirEntry The absolute path to the new directory.
730 * @param {function} opt_callback Executed if the directory loads successfully. 775 * @param {function} opt_callback Executed if the directory loads successfully.
731 */ 776 */
732 DirectoryModel.prototype.changeDirectoryEntry_ = function(initial, dirEntry, 777 DirectoryModel.prototype.changeDirectoryEntry_ = function(initial, dirEntry,
733 opt_callback) { 778 opt_callback) {
779 if (this.shouldClearSearch(this.currentDirEntry_, dirEntry))
780 this.clearSearch();
734 var previous = this.currentDirEntry_; 781 var previous = this.currentDirEntry_;
735 this.currentDirEntry_ = dirEntry; 782 this.currentDirEntry_ = dirEntry;
736 function onRescanComplete() { 783 function onRescanComplete() {
737 if (opt_callback) 784 if (opt_callback)
738 opt_callback(); 785 opt_callback();
739 // For tests that open the dialog to empty directories, everything 786 // For tests that open the dialog to empty directories, everything
740 // is loaded at this point. 787 // is loaded at this point.
741 chrome.test.sendMessage('directory-change-complete'); 788 chrome.test.sendMessage('directory-change-complete');
742 } 789 }
743 this.updateRootsListSelection_(); 790 this.updateRootsListSelection_();
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
1102 // Re-place the entry into the roots data model to force re-rendering. 1149 // Re-place the entry into the roots data model to force re-rendering.
1103 this.rootsList_.splice(index, 1, entry); 1150 this.rootsList_.splice(index, 1, entry);
1104 1151
1105 if (rootPath == this.rootPath) { 1152 if (rootPath == this.rootPath) {
1106 // TODO(kaznacheev): Consider changing to the most recently used root. 1153 // TODO(kaznacheev): Consider changing to the most recently used root.
1107 this.changeDirectory(this.getDefaultDirectory()); 1154 this.changeDirectory(this.getDefaultDirectory());
1108 } 1155 }
1109 }; 1156 };
1110 1157
1111 /** 1158 /**
1159 * Performs search and displays results. The search type is dependent on the
1160 * current directory. If we are currently on gdata, server side content search
1161 * over gdata mount point. If the current directory is not on the gdata, file
1162 * name search over current directory wil be performed.
1163 *
1164 * @param {string} query Query that will be searched for.
1165 */
1166 DirectoryModel.prototype.search = function(query) {
1167 if (!query) {
1168 this.clearSearch();
1169 return;
1170 }
1171
1172 // If we are offline, let's fallback to file name search inside dir.
1173 if (this.getRootType() == DirectoryModel.RootType.GDATA &&
1174 !util.isOffline()) {
1175 var self = this;
1176 // Create shadow directory which will contein search results.
1177 this.root_.getDirectory(util.createGDataSearchPath(query),
1178 {create: false},
1179 function(dir) {
1180 self.updateCurrentDirAndSearch(dir);
1181 });
1182 } else {
1183 this.addFilter(
1184 'searchbox',
1185 function(e) {
1186 return e.name.substring(0, query.length) == query;
1187 });
1188 }
1189 };
1190
1191 /**
1192 * Changed |currentDirEntry_| and triggers rescan for gdata search.
1193 * @param {Entry} searchDir Directory entry that will be used to collect search
1194 * results.
1195 */
1196 DirectoryModel.prototype.updateCurrentDirAndSearch = function(searchDir) {
1197 if (!util.isGDataSearchPath(this.currentDirEntry_.fullPath))
1198 this.lastNonGDataSearchDir_ = this.currentDirEntry_;
1199 // We have to update currentDirEntry_ so we ignore DirectoryChanged
1200 // notifications.
1201 this.currentDirEntry_ = searchDir;
SeRya 2012/05/10 08:44:16 It's better but still flawed. You shouldn't change
tbarzic 2012/05/10 23:28:02 Done.
1202 this.rescanSoon();
1203 };
1204
1205 /**
1206 * Checks if the search state of the directory should be reset when changing
1207 * directories.
1208 * @param {Entry} oldEntry Dir entry from which directory should be changed.
1209 * @param {Entry} newEntry Dire entry to which directory should be changed.
1210 * @return {boolean} Should search state be cleared.
1211 */
1212 DirectoryModel.prototype.shouldClearSearch = function(oldEntry, newEntry) {
1213 var isOldOnGData = DirectoryModel.getRootType(oldEntry.fullPath) ==
1214 DirectoryModel.RootType.GDATA;
1215 var isNewOnGData = DirectoryModel.getRootType(newEntry.fullPath) ==
1216 DirectoryModel.RootType.GDATA;
1217
1218 // Searches on gdata root and non gdata root are different, so let's just undo
1219 // the search if the search type for directories changes.
1220 // Also, if we are changing directory on gdata, We should reset directory
1221 // state if it was changed by a search in progress.
1222 return !util.isOffline() && (isNewOnGData || (isOldOnGData != isNewOnGData));
1223 };
1224
1225 /**
1226 * Clears any state set by previous searches.
1227 */
1228 DirectoryModel.prototype.clearSearch = function() {
1229 if (this.lastNonGDataSearchDir_)
1230 this.currentDirEntry_ = this.lastNonGDataSearchDir_;
1231 this.lastNonGDataSearchDir_ = null;
1232 // This will trigger rescan.
1233 this.removeFilter('searchbox');
1234 };
1235
1236 /**
1112 * @param {string} path Any path. 1237 * @param {string} path Any path.
1113 * @return {string} The root path. 1238 * @return {string} The root path.
1114 */ 1239 */
1115 DirectoryModel.getRootPath = function(path) { 1240 DirectoryModel.getRootPath = function(path) {
1116 var type = DirectoryModel.getRootType(path); 1241 var type = DirectoryModel.getRootType(path);
1117 1242
1118 if (type == DirectoryModel.RootType.DOWNLOADS) 1243 if (type == DirectoryModel.RootType.DOWNLOADS)
1119 return '/' + DirectoryModel.DOWNLOADS_DIRECTORY; 1244 return '/' + DirectoryModel.DOWNLOADS_DIRECTORY;
1120 if (type == DirectoryModel.RootType.GDATA) 1245 if (type == DirectoryModel.RootType.GDATA)
1121 return '/' + DirectoryModel.GDATA_DIRECTORY; 1246 return '/' + DirectoryModel.GDATA_DIRECTORY;
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1262 /** 1387 /**
1263 * @private 1388 * @private
1264 */ 1389 */
1265 DirectoryModel.Scanner.prototype.recordMetrics_ = function() { 1390 DirectoryModel.Scanner.prototype.recordMetrics_ = function() {
1266 metrics.recordInterval('DirectoryScan'); 1391 metrics.recordInterval('DirectoryScan');
1267 if (this.dir_.fullPath == 1392 if (this.dir_.fullPath ==
1268 '/' + DirectoryModel.DOWNLOADS_DIRECTORY) { 1393 '/' + DirectoryModel.DOWNLOADS_DIRECTORY) {
1269 metrics.recordMediumCount('DownloadsCount', this.list_.length); 1394 metrics.recordMediumCount('DownloadsCount', this.list_.length);
1270 } 1395 }
1271 }; 1396 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698