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

Unified 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 side-by-side diff with in-line comments
Download patch
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..b85f495e174fe702c5878d4e3ddecb59cfc93b2c 100644
--- a/chrome/browser/resources/file_manager/js/directory_model.js
+++ b/chrome/browser/resources/file_manager/js/directory_model.js
@@ -57,6 +57,21 @@ function DirectoryModel(root, singleSelection, showGData, metadataCache) {
* @type {Object.<string, boolean>}
*/
this.volumeReadOnlyStatus_ = {};
+
+ /**
+ * Directory in which search results are displayed. Not null iff search
+ * results are being displayed.
+ * @private
+ * @type {Entry}
+ */
+ this.searchDirEntry_ = null;
+
+ /**
+ * Is search in progress.
+ * @private
+ * @type {boolean}
+ */
+ this.isSearching_ = false;
}
/**
@@ -93,6 +108,21 @@ DirectoryModel.DOWNLOADS_DIRECTORY = 'Downloads';
DirectoryModel.GDATA_DIRECTORY = 'gdata';
/**
+ * Root path used for displaying gdata content search results.
+ * Search results will be shown in directory 'GDATA_SEARCH_ROOT_PATH/query'.
+ *
+ * @const
+ * @type {string}
+ */
+DirectoryModel.GDATA_SEARCH_ROOT_PATH = '/gdata/.search';
+
+/**
+ * @const
+ * @type {Array.<string>}
+ */
+DirectoryModel.GDATA_SEARCH_ROOT_COMPONENTS = ['', 'gdata', '.search'];
+
+/**
* DirectoryModel extends cr.EventTarget.
*/
DirectoryModel.prototype.__proto__ = cr.EventTarget.prototype;
@@ -150,6 +180,20 @@ DirectoryModel.prototype.isReadOnly = function() {
};
/**
+ * @return {boolean} True if search is in progress.
+ */
+DirectoryModel.prototype.isSearching = function() {
+ return this.isSearching_;
+};
+
+/**
+ * @return {boolean} True if we are currently showing search results.
+ */
+DirectoryModel.prototype.isOnGDataSearchDir = function() {
+ return this.getSearchOrCurrentDirEntry() != this.getCurrentDirEntry();
+};
+
+/**
* @param {strin} path Path to check.
* @return {boolean} True if the |path| is read only.
*/
@@ -205,6 +249,16 @@ DirectoryModel.prototype.getCurrentDirEntry = function() {
};
/**
+ * If search results are being displayed, returns search directory, else returns
+ * current directory.
+ *
+ * @return {DirectoryEntry} search or directory entry.
+ */
+DirectoryModel.prototype.getSearchOrCurrentDirEntry = function() {
+ return this.searchDirEntry_ || this.currentDirEntry_;
+};
+
+/**
* @return {string} Path for the current directory.
*/
DirectoryModel.prototype.getCurrentDirPath = function() {
@@ -409,7 +463,7 @@ DirectoryModel.prototype.createScanner_ = function(list, successCallback) {
}
return new DirectoryModel.Scanner(
- this.currentDirEntry_,
+ this.getSearchOrCurrentDirEntry(),
list,
onSuccess,
onFailure,
@@ -497,6 +551,38 @@ DirectoryModel.prototype.prefetchCacheForSorting_ = function(entries,
};
/**
+ * Gets name that should be displayed 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;
+};
+
+/**
+ * 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
dgozman 2012/05/15 11:25:06 typo: it -> if
tbarzic 2012/05/16 03:50:04 Done.
+ * entry, |newName| will be used.
dgozman 2012/05/15 11:25:06 typo: newName -> displayName
tbarzic 2012/05/16 03:50:04 Done.
+ *
+ * @private
+ * @param {Entry} entry Entry which is being renamed.
+ * @param {string} displayName The new file name provided by user.
+ * @return {string} File name that should be used in renaming filesystem
+ * operations.
+ */
+DirectoryModel.prototype.getEntryName_ = function(entry, displayName) {
dgozman 2012/05/15 11:25:06 Confusing name. I'd say that getEntryName == entry
tbarzic 2012/05/16 03:50:04 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 + '.' + displayName :
+ displayName;
+};
+
+/**
* Delete the list of files and directories from filesystem and
* update the file list.
* @param {Array.<Entry>} entries Entries to delete.
@@ -533,11 +619,16 @@ DirectoryModel.prototype.deleteEntries = function(entries, opt_callback) {
* @param {string} name Filename.
*/
DirectoryModel.prototype.onEntryChanged = function(name) {
- var currentEntry = this.currentDirEntry_;
+ var currentEntry = this.getSearchOrCurrentDirEntry();
+ if (currentEntry != this.currentDirEntry_)
+ return;
var dm = this.fileList_;
var self = this;
function onEntryFound(entry) {
+ // Do nothing if current directory changed during async operations.
+ if (self.currentDirEntry_ != currentEntry)
dgozman 2012/05/15 11:25:06 This should probably be: if (self.getSearchOrCurre
tbarzic 2012/05/16 03:50:04 Done.
+ return;
self.prefetchCacheForSorting_([entry], function() {
// Do nothing if current directory changed during async operations.
if (self.currentDirEntry_ != currentEntry)
@@ -565,7 +656,7 @@ DirectoryModel.prototype.onEntryChanged = function(name) {
dm.splice(index, 1);
};
- util.resolvePath(this.currentDirEntry_, name, onEntryFound, onError);
+ util.resolvePath(currentEntry, name, onEntryFound, onError);
};
/**
@@ -584,11 +675,12 @@ DirectoryModel.prototype.findIndexByName_ = function(name) {
/**
* Rename the entry in the filesystem and update the file list.
* @param {Entry} entry Entry to rename.
- * @param {string} newName New name.
+ * @param {string} newDisplayName New name.
* @param {function} errorCallback Called on error.
* @param {function} opt_successCallback Called on success.
*/
-DirectoryModel.prototype.renameEntry = function(entry, newName, errorCallback,
+DirectoryModel.prototype.renameEntry = function(entry, newDisplayName,
+ errorCallback,
opt_successCallback) {
var self = this;
function onSuccess(newEntry) {
@@ -597,25 +689,31 @@ 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 newEntryName = this.getEntryName_(entry, newDisplayName);
+ entry.moveTo(this.getSearchOrCurrentDirEntry(), newEntryName, onSuccess,
+ errorCallback);
};
/**
* Checks if current directory contains a file or directory with this name.
- * @param {string} newName Name to check.
+ * @param {string} entry Entry to which newName will be given.
+ * @param {string} displayName 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, displayName, callback) {
+ var entryName = this.getEntryName_(entry, displayName);
+
+ util.resolvePath(this.getSearchOrCurrentDirEntry(), entryName,
dgozman 2012/05/15 11:25:06 What if new renamed name does not conform to searc
tbarzic 2012/05/16 03:50:04 this case is handled in gdata code (a bit hacky, b
function(entry) {
callback(true, entry.isFile);
},
@@ -661,7 +759,15 @@ DirectoryModel.prototype.createDirectory = function(name, successCallback,
* @param {string} path New current directory path.
*/
DirectoryModel.prototype.changeDirectory = function(path) {
- this.resolveDirectory(path, function(directoryEntry) {
+ var targetPath = path;
+ // We should not be changing directory to gdata search path. If we do, default
+ // to gdata root.
+ if (DirectoryModel.isGDataSearchPath(path)) {
+ console.error('Attempt to change directory to search path.');
+ targetPath = '/' + DirectoryModel.GDATA_DIRECTORY;
+ }
+
+ this.resolveDirectory(targetPath, function(directoryEntry) {
this.changeDirectoryEntry_(false, directoryEntry);
}.bind(this), function(error) {
console.error('Error changing directory to ' + path + ': ', error);
@@ -731,6 +837,7 @@ DirectoryModel.prototype.changeDirectoryOrRoot = function(path) {
*/
DirectoryModel.prototype.changeDirectoryEntry_ = function(initial, dirEntry,
opt_callback) {
+ this.clearSearch_();
var previous = this.currentDirEntry_;
this.currentDirEntry_ = dirEntry;
function onRescanComplete() {
@@ -1109,6 +1216,56 @@ 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;
+ }
+
+ this.isSearching_ = true;
+
+ // 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.
dgozman 2012/05/15 11:25:06 typo: contein
tbarzic 2012/05/16 03:50:04 Done.
+ this.root_.getDirectory(DirectoryModel.createGDataSearchPath(query),
+ {create: false},
+ function(dir) {
+ self.searchDirEntry_ = dir;
+ self.rescanSoon();
+ },
+ this.clearSearch_.bind(this));
+ } else {
+ this.searchDirEntry_ = this.currentDirEntry_;
+ this.addFilter(
+ 'searchbox',
+ function(e) {
+ return e.name.substring(0, query.length) == query;
+ });
+ }
+};
+
+
+/**
+ * Clears any state set by previous searches.
+ * @private
+ */
+DirectoryModel.prototype.clearSearch_ = function() {
+ this.searchDirEntry_ = null;
+ this.isSearching_ = false;
+ // This will trigger rescan.
+ this.removeFilter('searchbox');
dgozman 2012/05/15 11:25:06 We may not have this filter present. This will pro
tbarzic 2012/05/16 03:50:04 I haven't seen the exception when we are removing
+};
+
+/**
* @param {string} path Any path.
* @return {string} The root path.
*/
@@ -1173,6 +1330,28 @@ DirectoryModel.isRootPath = function(path) {
};
/**
+ * Checks if the provided path is under gdata search.
+ *
+ * @param {string} path Path to be tested.
+ * @return {boolean} Is the path gdata search path.
+ */
+DirectoryModel.isGDataSearchPath = function(path) {
+ return path == DirectoryModel.GDATA_SEARCH_ROOT_PATH ||
+ path.search(DirectoryModel.GDATA_SEARCH_ROOT_PATH + '/') == 0;
dgozman 2012/05/15 11:25:06 search -> indexOf ?
tbarzic 2012/05/16 03:50:04 Done.
+};
+
+/**
+ * Creates directory path in which gdata content search results for |query|
+ * should be displayed.
+ *
+ * @param {string} query Search query.
+ * @return {string} Virtual directory path for search results.
+ */
+DirectoryModel.createGDataSearchPath = function(query) {
+ return DirectoryModel.GDATA_SEARCH_ROOT_PATH + '/' + query;
+};
+
+/**
* @constructor
* @extends cr.EventTarget
* @param {DirectoryEntry} dir Directory to scan.

Powered by Google App Engine
This is Rietveld 408576698