Chromium Code Reviews| Index: chrome/browser/resources/file_manager/js/directory_model.js |
| diff --git a/chrome/browser/resources/file_manager/js/directory_model.js b/chrome/browser/resources/file_manager/js/directory_model.js |
| index 0cc59331dc9f9b8719b390d0b09362e8b5c02c60..5f7f56db78b6588b97152d4def0b5c34acb080f8 100644 |
| --- a/chrome/browser/resources/file_manager/js/directory_model.js |
| +++ b/chrome/browser/resources/file_manager/js/directory_model.js |
| @@ -57,6 +57,14 @@ function DirectoryModel(root, singleSelection, showGData, metadataCache) { |
| * @type {Object.<string, boolean>} |
| */ |
| this.volumeReadOnlyStatus_ = {}; |
| + |
| + /** |
| + * File path of the last directory that is not under virtual search directory. |
| + * This is the path to go to when the search box content clears on GData. |
| + * @private |
| + * @type {string} |
| + */ |
| + this.lastNonGDataSearchDir_ = null; |
| } |
| /** |
| @@ -497,6 +505,18 @@ DirectoryModel.prototype.prefetchCacheForSorting_ = function(entries, |
| }; |
| /** |
| + * Gets name that should be dispalyed in the UI for the entry. |
| + * @param {string} path Full path of the entry whose display name we are |
| + * getting. |
| + * @param {string} defaultName Default name to use if no name is calculated. |
| + * @return {string} Name to be used for display. |
| + */ |
| +DirectoryModel.prototype.getDisplayName = function(path, defaultName) { |
| + var searchResultName = util.getFileAndDisplayNameForGDataSearchResult(path); |
| + return searchResultName ? searchResultName.displayName : defaultName; |
| +}; |
| + |
| +/** |
| * Delete the list of files and directories from filesystem and |
| * update the file list. |
| * @param {Array.<Entry>} entries Entries to delete. |
| @@ -597,25 +617,30 @@ DirectoryModel.prototype.renameEntry = function(entry, newName, errorCallback, |
| var index = fileList.indexOf(entry); |
| if (index >= 0) |
| fileList.splice(index, 1, newEntry); |
| - self.selectEntry(newName); |
| + self.selectEntry(newEntry.name); |
| // If the entry doesn't exist in the list it mean that it updated from |
| // outside (probably by directory rescan). |
| if (opt_successCallback) |
| opt_successCallback(); |
| }); |
| } |
| - entry.moveTo(this.currentDirEntry_, newName, onSuccess, errorCallback); |
| + |
| + var newNameToUse = this.getNameToUseInRenaming_(entry, newName); |
| + entry.moveTo(this.currentDirEntry_, newNameToUse, onSuccess, errorCallback); |
| }; |
| /** |
| * Checks if current directory contains a file or directory with this name. |
| + * @param {string} entry Entry to which newName will be given. |
| * @param {string} newName Name to check. |
| * @param {function(boolean, boolean?)} callback Called when the result's |
| * available. First parameter is true if the entry exists and second |
| * is true if it's a file. |
| */ |
| -DirectoryModel.prototype.doesExist = function(newName, callback) { |
| - util.resolvePath(this.currentDirEntry_, newName, |
| +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.
|
| + var newNameToUse = this.getNameToUseInRenaming_(entry, newName); |
| + |
| + util.resolvePath(this.currentDirEntry_, newNameToUse, |
| function(entry) { |
| callback(true, entry.isFile); |
| }, |
| @@ -623,6 +648,26 @@ DirectoryModel.prototype.doesExist = function(newName, callback) { |
| }; |
| /** |
| + * Creates file name that should be used as a new file name in filesystem |
| + * operations while renaming. It the given entry is not a gdata search result |
| + * entry, |newName| will be used. |
| + * |
| + * @private |
| + * @param {Entry} entry Entry which is being renamed. |
| + * @param {string} newName The new file name provided by user. |
| + * @return {string} File name that should be used in renaming filesystem |
| + * operations. |
| + */ |
| +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.
|
| + // If we are renaming gdata search result, we'll have to format newName to |
| + // use in file system operation like: <resource_id>.<file_name>. |
| + var searchResultName = |
| + util.getFileAndDisplayNameForGDataSearchResult(entry.fullPath); |
| + return searchResultName ? searchResultName.resourceId + '.' + newName : |
| + newName; |
| +}; |
| + |
| +/** |
| * Creates directory and updates the file list. |
| * |
| * @param {string} name Directory name. |
| @@ -731,6 +776,8 @@ DirectoryModel.prototype.changeDirectoryOrRoot = function(path) { |
| */ |
| DirectoryModel.prototype.changeDirectoryEntry_ = function(initial, dirEntry, |
| opt_callback) { |
| + if (this.shouldClearSearch(this.currentDirEntry_, dirEntry)) |
| + this.clearSearch(); |
| var previous = this.currentDirEntry_; |
| this.currentDirEntry_ = dirEntry; |
| function onRescanComplete() { |
| @@ -1109,6 +1156,84 @@ DirectoryModel.prototype.prepareUnmount = function(rootPath) { |
| }; |
| /** |
| + * Performs search and displays results. The search type is dependent on the |
| + * current directory. If we are currently on gdata, server side content search |
| + * over gdata mount point. If the current directory is not on the gdata, file |
| + * name search over current directory wil be performed. |
| + * |
| + * @param {string} query Query that will be searched for. |
| + */ |
| +DirectoryModel.prototype.search = function(query) { |
| + if (!query) { |
| + this.clearSearch(); |
| + return; |
| + } |
| + |
| + // If we are offline, let's fallback to file name search inside dir. |
| + if (this.getRootType() == DirectoryModel.RootType.GDATA && |
| + !util.isOffline()) { |
| + var self = this; |
| + // Create shadow directory which will contein search results. |
| + this.root_.getDirectory(util.createGDataSearchPath(query), |
| + {create: false}, |
| + function(dir) { |
| + self.updateCurrentDirAndSearch(dir); |
| + }); |
| + } else { |
| + this.addFilter( |
| + 'searchbox', |
| + function(e) { |
| + return e.name.substring(0, query.length) == query; |
| + }); |
| + } |
| +}; |
| + |
| +/** |
| + * Changed |currentDirEntry_| and triggers rescan for gdata search. |
| + * @param {Entry} searchDir Directory entry that will be used to collect search |
| + * results. |
| + */ |
| +DirectoryModel.prototype.updateCurrentDirAndSearch = function(searchDir) { |
| + if (!util.isGDataSearchPath(this.currentDirEntry_.fullPath)) |
| + this.lastNonGDataSearchDir_ = this.currentDirEntry_; |
| + // We have to update currentDirEntry_ so we ignore DirectoryChanged |
| + // notifications. |
| + 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.
|
| + this.rescanSoon(); |
| +}; |
| + |
| +/** |
| + * Checks if the search state of the directory should be reset when changing |
| + * directories. |
| + * @param {Entry} oldEntry Dir entry from which directory should be changed. |
| + * @param {Entry} newEntry Dire entry to which directory should be changed. |
| + * @return {boolean} Should search state be cleared. |
| + */ |
| +DirectoryModel.prototype.shouldClearSearch = function(oldEntry, newEntry) { |
| + var isOldOnGData = DirectoryModel.getRootType(oldEntry.fullPath) == |
| + DirectoryModel.RootType.GDATA; |
| + var isNewOnGData = DirectoryModel.getRootType(newEntry.fullPath) == |
| + DirectoryModel.RootType.GDATA; |
| + |
| + // Searches on gdata root and non gdata root are different, so let's just undo |
| + // the search if the search type for directories changes. |
| + // Also, if we are changing directory on gdata, We should reset directory |
| + // state if it was changed by a search in progress. |
| + return !util.isOffline() && (isNewOnGData || (isOldOnGData != isNewOnGData)); |
| +}; |
| + |
| +/** |
| + * Clears any state set by previous searches. |
| + */ |
| +DirectoryModel.prototype.clearSearch = function() { |
| + if (this.lastNonGDataSearchDir_) |
| + this.currentDirEntry_ = this.lastNonGDataSearchDir_; |
| + this.lastNonGDataSearchDir_ = null; |
| + // This will trigger rescan. |
| + this.removeFilter('searchbox'); |
| +}; |
| + |
| +/** |
| * @param {string} path Any path. |
| * @return {string} The root path. |
| */ |