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

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: fix indent 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
« no previous file with comments | « no previous file | chrome/browser/resources/file_manager/js/file_copy_manager.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 48
49 // The map 'name' -> callback. Callbacks are function(entry) -> boolean. 49 // The map 'name' -> callback. Callbacks are function(entry) -> boolean.
50 this.filters_ = {}; 50 this.filters_ = {};
51 this.setFilterHidden(true); 51 this.setFilterHidden(true);
52 52
53 /** 53 /**
54 * @private 54 * @private
55 * @type {Object.<string, boolean>} 55 * @type {Object.<string, boolean>}
56 */ 56 */
57 this.volumeReadOnlyStatus_ = {}; 57 this.volumeReadOnlyStatus_ = {};
58
59 /**
60 * Directory in which search results are displayed. Not null iff search
61 * results are being displayed.
62 * @private
63 * @type {Entry}
64 */
65 this.searchDirEntry_ = null;
66
67 /**
68 * Is search in progress.
69 * @private
70 * @type {boolean}
71 */
72 this.isSearching_ = false;
58 } 73 }
59 74
60 /** 75 /**
61 * The name of the directory containing externally 76 * The name of the directory containing externally
62 * mounted removable storage volumes. 77 * mounted removable storage volumes.
63 */ 78 */
64 DirectoryModel.REMOVABLE_DIRECTORY = 'removable'; 79 DirectoryModel.REMOVABLE_DIRECTORY = 'removable';
65 80
66 /** 81 /**
67 * The name of the directory containing externally 82 * The name of the directory containing externally
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 * GData access mode: lazy (GData root displayed, no content is fetched yet). 114 * GData access mode: lazy (GData root displayed, no content is fetched yet).
100 */ 115 */
101 DirectoryModel.GDATA_ACCESS_LAZY = 1; 116 DirectoryModel.GDATA_ACCESS_LAZY = 1;
102 117
103 /** 118 /**
104 * GData access mode: full (GData root displayed, content is available). 119 * GData access mode: full (GData root displayed, content is available).
105 */ 120 */
106 DirectoryModel.GDATA_ACCESS_FULL = 2; 121 DirectoryModel.GDATA_ACCESS_FULL = 2;
107 122
108 /** 123 /**
124 * Root path used for displaying gdata content search results.
125 * Search results will be shown in directory 'GDATA_SEARCH_ROOT_PATH/query'.
126 *
127 * @const
128 * @type {string}
129 */
130 DirectoryModel.GDATA_SEARCH_ROOT_PATH = '/drive/.search';
131
132 /**
133 * @const
134 * @type {Array.<string>}
135 */
136 DirectoryModel.GDATA_SEARCH_ROOT_COMPONENTS = ['', 'drive', '.search'];
137
138 /**
109 * DirectoryModel extends cr.EventTarget. 139 * DirectoryModel extends cr.EventTarget.
110 */ 140 */
111 DirectoryModel.prototype.__proto__ = cr.EventTarget.prototype; 141 DirectoryModel.prototype.__proto__ = cr.EventTarget.prototype;
112 142
113 /** 143 /**
114 * @return {cr.ui.ArrayDataModel} Files in the current directory. 144 * @return {cr.ui.ArrayDataModel} Files in the current directory.
115 */ 145 */
116 DirectoryModel.prototype.getFileList = function() { 146 DirectoryModel.prototype.getFileList = function() {
117 return this.fileList_; 147 return this.fileList_;
118 }; 148 };
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 }; 200 };
171 201
172 /** 202 /**
173 * @return {boolean} True if current directory is read only. 203 * @return {boolean} True if current directory is read only.
174 */ 204 */
175 DirectoryModel.prototype.isReadOnly = function() { 205 DirectoryModel.prototype.isReadOnly = function() {
176 return this.isPathReadOnly(this.getCurrentRootPath()); 206 return this.isPathReadOnly(this.getCurrentRootPath());
177 }; 207 };
178 208
179 /** 209 /**
180 * @param {string} path Path to check. 210 * @return {boolean} True if search is in progress.
211 */
212 DirectoryModel.prototype.isSearching = function() {
213 return this.isSearching_;
214 };
215
216 /**
217 * @return {boolean} True if we are currently showing search results.
218 */
219 DirectoryModel.prototype.isOnGDataSearchDir = function() {
220 return this.getSearchOrCurrentDirEntry() != this.getCurrentDirEntry();
221 };
222
223 /**
224 * @param {strin} path Path to check.
181 * @return {boolean} True if the |path| is read only. 225 * @return {boolean} True if the |path| is read only.
182 */ 226 */
183 DirectoryModel.prototype.isPathReadOnly = function(path) { 227 DirectoryModel.prototype.isPathReadOnly = function(path) {
184 switch (DirectoryModel.getRootType(path)) { 228 switch (DirectoryModel.getRootType(path)) {
185 case DirectoryModel.RootType.REMOVABLE: 229 case DirectoryModel.RootType.REMOVABLE:
186 return !!this.volumeReadOnlyStatus_[DirectoryModel.getRootPath(path)]; 230 return !!this.volumeReadOnlyStatus_[DirectoryModel.getRootPath(path)];
187 case DirectoryModel.RootType.ARCHIVE: 231 case DirectoryModel.RootType.ARCHIVE:
188 return true; 232 return true;
189 case DirectoryModel.RootType.DOWNLOADS: 233 case DirectoryModel.RootType.DOWNLOADS:
190 return false; 234 return false;
(...skipping 24 matching lines...) Expand all
215 }; 259 };
216 260
217 /** 261 /**
218 * @return {DirectoryEntry} Current directory. 262 * @return {DirectoryEntry} Current directory.
219 */ 263 */
220 DirectoryModel.prototype.getCurrentDirEntry = function() { 264 DirectoryModel.prototype.getCurrentDirEntry = function() {
221 return this.currentDirEntry_; 265 return this.currentDirEntry_;
222 }; 266 };
223 267
224 /** 268 /**
269 * If search results are being displayed, returns search directory, else returns
270 * current directory.
271 *
272 * @return {DirectoryEntry} search or directory entry.
273 */
274 DirectoryModel.prototype.getSearchOrCurrentDirEntry = function() {
275 return this.searchDirEntry_ || this.currentDirEntry_;
276 };
277
278 /**
225 * @return {string} Path for the current directory. 279 * @return {string} Path for the current directory.
226 */ 280 */
227 DirectoryModel.prototype.getCurrentDirPath = function() { 281 DirectoryModel.prototype.getCurrentDirPath = function() {
228 return this.currentDirEntry_.fullPath; 282 return this.currentDirEntry_.fullPath;
229 }; 283 };
230 284
231 /** 285 /**
232 * @private 286 * @private
233 * @return {Array.<string>} Names of selected files. 287 * @return {Array.<string>} Names of selected files.
234 */ 288 */
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 DirectoryModel.prototype.addFilter = function(name, filter) { 383 DirectoryModel.prototype.addFilter = function(name, filter) {
330 this.filters_[name] = filter; 384 this.filters_[name] = filter;
331 this.rescanSoon(); 385 this.rescanSoon();
332 }; 386 };
333 387
334 /** 388 /**
335 * Remove one of the directory contents filters, specified by name. 389 * Remove one of the directory contents filters, specified by name.
336 * @param {string} name Identifier of a filter. 390 * @param {string} name Identifier of a filter.
337 */ 391 */
338 DirectoryModel.prototype.removeFilter = function(name) { 392 DirectoryModel.prototype.removeFilter = function(name) {
339 delete this.filters_[name]; 393 if (this.filters_[name])
394 delete this.filters_[name];
340 this.rescanSoon(); 395 this.rescanSoon();
341 }; 396 };
342 397
343 /** 398 /**
344 * Schedule rescan with short delay. 399 * Schedule rescan with short delay.
345 */ 400 */
346 DirectoryModel.prototype.rescanSoon = function() { 401 DirectoryModel.prototype.rescanSoon = function() {
347 this.scheduleRescan(SHORT_RESCAN_INTERVAL); 402 this.scheduleRescan(SHORT_RESCAN_INTERVAL);
348 }; 403 };
349 404
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 } 474 }
420 } 475 }
421 476
422 function onFailure() { 477 function onFailure() {
423 self.scanFailures_++; 478 self.scanFailures_++;
424 if (self.scanFailures_ <= 1) 479 if (self.scanFailures_ <= 1)
425 self.rescanLater(); 480 self.rescanLater();
426 } 481 }
427 482
428 return new DirectoryModel.Scanner( 483 return new DirectoryModel.Scanner(
429 this.currentDirEntry_, 484 this.getSearchOrCurrentDirEntry(),
430 list, 485 list,
431 onSuccess, 486 onSuccess,
432 onFailure, 487 onFailure,
433 this.prefetchCacheForSorting_.bind(this), 488 this.prefetchCacheForSorting_.bind(this),
434 this.filters_); 489 this.filters_);
435 }; 490 };
436 491
437 /** 492 /**
438 * @private 493 * @private
439 * @param {Array.<Entry>} entries List of files. 494 * @param {Array.<Entry>} entries List of files.
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 callback) { 561 callback) {
507 var field = this.fileList_.sortStatus.field; 562 var field = this.fileList_.sortStatus.field;
508 if (field) { 563 if (field) {
509 this.prepareSortEntries_(entries, field, callback); 564 this.prepareSortEntries_(entries, field, callback);
510 } else { 565 } else {
511 callback(); 566 callback();
512 } 567 }
513 }; 568 };
514 569
515 /** 570 /**
571 * Gets name that should be displayed in the UI for the entry.
572 * @param {string} path Full path of the entry whose display name we are
573 * getting.
574 * @param {string} defaultName Default name to use if no name is calculated.
575 * @return {string} Name to be used for display.
576 */
577 DirectoryModel.prototype.getDisplayName = function(path, defaultName) {
578 var searchResultName = util.getFileAndDisplayNameForGDataSearchResult(path);
579 return searchResultName ? searchResultName.displayName : defaultName;
580 };
581
582 /**
583 * Creates file name that should be used as a new file name in filesystem
584 * operations while renaming. If the given entry is not a gdata search result
585 * entry, |displayName| will be used.
586 *
587 * @private
588 * @param {Entry} entry Entry which is being renamed.
589 * @param {string} displayName The new file name provided by user.
590 * @return {string} File name that should be used in renaming filesystem
591 * operations.
592 */
593 DirectoryModel.prototype.getEntryNameForRename_ = function(entry, displayName) {
594 // If we are renaming gdata search result, we'll have to format newName to
595 // use in file system operation like: <resource_id>.<file_name>.
596 var searchResultName =
597 util.getFileAndDisplayNameForGDataSearchResult(entry.fullPath);
598 return searchResultName ? searchResultName.resourceId + '.' + displayName :
599 displayName;
600 };
601
602 /**
516 * Delete the list of files and directories from filesystem and 603 * Delete the list of files and directories from filesystem and
517 * update the file list. 604 * update the file list.
518 * @param {Array.<Entry>} entries Entries to delete. 605 * @param {Array.<Entry>} entries Entries to delete.
519 * @param {function()=} opt_callback Called when finished. 606 * @param {function()=} opt_callback Called when finished.
520 */ 607 */
521 DirectoryModel.prototype.deleteEntries = function(entries, opt_callback) { 608 DirectoryModel.prototype.deleteEntries = function(entries, opt_callback) {
522 var downcount = entries.length + 1; 609 var downcount = entries.length + 1;
523 610
524 var onComplete = opt_callback ? function() { 611 var onComplete = opt_callback ? function() {
525 if (--downcount == 0) 612 if (--downcount == 0)
(...skipping 16 matching lines...) Expand all
542 onSuccess, 629 onSuccess,
543 util.flog('Error deleting ' + entry.fullPath, onComplete)); 630 util.flog('Error deleting ' + entry.fullPath, onComplete));
544 } 631 }
545 onComplete(); 632 onComplete();
546 }; 633 };
547 634
548 /** 635 /**
549 * @param {string} name Filename. 636 * @param {string} name Filename.
550 */ 637 */
551 DirectoryModel.prototype.onEntryChanged = function(name) { 638 DirectoryModel.prototype.onEntryChanged = function(name) {
552 var currentEntry = this.currentDirEntry_; 639 var currentEntry = this.getSearchOrCurrentDirEntry();
640 if (currentEntry != this.currentDirEntry_)
641 return;
553 var dm = this.fileList_; 642 var dm = this.fileList_;
554 var self = this; 643 var self = this;
555 644
556 function onEntryFound(entry) { 645 function onEntryFound(entry) {
646 // Do nothing if current directory changed during async operations.
647 if (self.getSearchOrCurrentDirEntry() != currentEntry)
648 return;
557 self.prefetchCacheForSorting_([entry], function() { 649 self.prefetchCacheForSorting_([entry], function() {
558 // Do nothing if current directory changed during async operations. 650 // Do nothing if current directory changed during async operations.
559 if (self.currentDirEntry_ != currentEntry) 651 if (self.getSearchOrCurrentDirEntry() != currentEntry)
560 return; 652 return;
561 653
562 var index = self.findIndexByName_(name); 654 var index = self.findIndexByName_(name);
563 if (index >= 0) 655 if (index >= 0)
564 dm.splice(index, 1, entry); 656 dm.splice(index, 1, entry);
565 else 657 else
566 dm.splice(dm.length, 0, entry); 658 dm.splice(dm.length, 0, entry);
567 }); 659 });
568 }; 660 };
569 661
570 function onError(err) { 662 function onError(err) {
571 // Do nothing if current directory changed during async operations. 663 // Do nothing if current directory changed during async operations.
572 if (self.currentDirEntry_ != currentEntry) 664 if (self.currentDirEntry_ != currentEntry)
573 return; 665 return;
574 if (err.code != FileError.NOT_FOUND_ERR) { 666 if (err.code != FileError.NOT_FOUND_ERR) {
575 self.rescanLater(); 667 self.rescanLater();
576 return; 668 return;
577 } 669 }
578 670
579 var index = self.findIndexByName_(name); 671 var index = self.findIndexByName_(name);
580 if (index >= 0) 672 if (index >= 0)
581 dm.splice(index, 1); 673 dm.splice(index, 1);
582 }; 674 };
583 675
584 util.resolvePath(this.currentDirEntry_, name, onEntryFound, onError); 676 util.resolvePath(currentEntry, name, onEntryFound, onError);
585 }; 677 };
586 678
587 /** 679 /**
588 * @private 680 * @private
589 * @param {string} name Filename. 681 * @param {string} name Filename.
590 * @return {number} The index in the fileList. 682 * @return {number} The index in the fileList.
591 */ 683 */
592 DirectoryModel.prototype.findIndexByName_ = function(name) { 684 DirectoryModel.prototype.findIndexByName_ = function(name) {
593 var dm = this.fileList_; 685 var dm = this.fileList_;
594 for (var i = 0; i < dm.length; i++) 686 for (var i = 0; i < dm.length; i++)
595 if (dm.item(i).name == name) 687 if (dm.item(i).name == name)
596 return i; 688 return i;
597 return -1; 689 return -1;
598 }; 690 };
599 691
600 /** 692 /**
601 * Rename the entry in the filesystem and update the file list. 693 * Rename the entry in the filesystem and update the file list.
602 * @param {Entry} entry Entry to rename. 694 * @param {Entry} entry Entry to rename.
603 * @param {string} newName New name. 695 * @param {string} newDisplayName New name.
604 * @param {function} errorCallback Called on error. 696 * @param {function} errorCallback Called on error.
605 * @param {function} opt_successCallback Called on success. 697 * @param {function} opt_successCallback Called on success.
606 */ 698 */
607 DirectoryModel.prototype.renameEntry = function(entry, newName, errorCallback, 699 DirectoryModel.prototype.renameEntry = function(entry, newDisplayName,
700 errorCallback,
608 opt_successCallback) { 701 opt_successCallback) {
609 var self = this; 702 var self = this;
610 function onSuccess(newEntry) { 703 function onSuccess(newEntry) {
611 self.prefetchCacheForSorting_([newEntry], function() { 704 self.prefetchCacheForSorting_([newEntry], function() {
612 var fileList = self.fileList_; 705 var fileList = self.fileList_;
613 var index = fileList.indexOf(entry); 706 var index = fileList.indexOf(entry);
614 if (index >= 0) 707 if (index >= 0)
615 fileList.splice(index, 1, newEntry); 708 fileList.splice(index, 1, newEntry);
616 self.selectEntry(newName); 709 self.selectEntry(newEntry.name);
617 // If the entry doesn't exist in the list it mean that it updated from 710 // If the entry doesn't exist in the list it mean that it updated from
618 // outside (probably by directory rescan). 711 // outside (probably by directory rescan).
619 if (opt_successCallback) 712 if (opt_successCallback)
620 opt_successCallback(); 713 opt_successCallback();
621 }); 714 });
622 } 715 }
623 entry.moveTo(this.currentDirEntry_, newName, onSuccess, errorCallback); 716
717 var newEntryName = this.getEntryNameForRename_(entry, newDisplayName);
718 entry.moveTo(this.getSearchOrCurrentDirEntry(), newEntryName, onSuccess,
719 errorCallback);
624 }; 720 };
625 721
626 /** 722 /**
627 * Checks if current directory contains a file or directory with this name. 723 * Checks if current directory contains a file or directory with this name.
628 * @param {string} newName Name to check. 724 * @param {string} entry Entry to which newName will be given.
725 * @param {string} displayName Name to check.
629 * @param {function(boolean, boolean?)} callback Called when the result's 726 * @param {function(boolean, boolean?)} callback Called when the result's
630 * available. First parameter is true if the entry exists and second 727 * available. First parameter is true if the entry exists and second
631 * is true if it's a file. 728 * is true if it's a file.
632 */ 729 */
633 DirectoryModel.prototype.doesExist = function(newName, callback) { 730 DirectoryModel.prototype.doesExist = function(entry, displayName, callback) {
634 util.resolvePath(this.currentDirEntry_, newName, 731 var entryName = this.getEntryNameForRename_(entry, displayName);
732
733 util.resolvePath(this.getSearchOrCurrentDirEntry(), entryName,
635 function(entry) { 734 function(entry) {
636 callback(true, entry.isFile); 735 callback(true, entry.isFile);
637 }, 736 },
638 callback.bind(window, false)); 737 callback.bind(window, false));
639 }; 738 };
640 739
641 /** 740 /**
642 * Creates directory and updates the file list. 741 * Creates directory and updates the file list.
643 * 742 *
644 * @param {string} name Directory name. 743 * @param {string} name Directory name.
(...skipping 25 matching lines...) Expand all
670 this.currentDirEntry_.getDirectory(name, {create: true, exclusive: true}, 769 this.currentDirEntry_.getDirectory(name, {create: true, exclusive: true},
671 onSuccess, errorCallback); 770 onSuccess, errorCallback);
672 }; 771 };
673 772
674 /** 773 /**
675 * Changes directory. Causes 'directory-change' event. 774 * Changes directory. Causes 'directory-change' event.
676 * 775 *
677 * @param {string} path New current directory path. 776 * @param {string} path New current directory path.
678 */ 777 */
679 DirectoryModel.prototype.changeDirectory = function(path) { 778 DirectoryModel.prototype.changeDirectory = function(path) {
680 this.resolveDirectory(path, function(directoryEntry) { 779 var targetPath = path;
780 // We should not be changing directory to gdata search path. If we do, default
781 // to gdata root.
782 if (DirectoryModel.isGDataSearchPath(path)) {
783 console.error('Attempt to change directory to search path.');
784 targetPath = '/' + DirectoryModel.GDATA_DIRECTORY;
785 }
786
787 this.resolveDirectory(targetPath, function(directoryEntry) {
681 this.changeDirectoryEntry_(false, directoryEntry); 788 this.changeDirectoryEntry_(false, directoryEntry);
682 }.bind(this), function(error) { 789 }.bind(this), function(error) {
683 console.error('Error changing directory to ' + path + ': ', error); 790 console.error('Error changing directory to ' + path + ': ', error);
684 }); 791 });
685 }; 792 };
686 793
687 /** 794 /**
688 * Resolves absolute directory path. Handles GData stub. 795 * Resolves absolute directory path. Handles GData stub.
689 * @param {string} path Path to the directory. 796 * @param {string} path Path to the directory.
690 * @param {function(DirectoryEntry} successCallback Success callback. 797 * @param {function(DirectoryEntry} successCallback Success callback.
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 * changed. 859 * changed.
753 * 860 *
754 * @private 861 * @private
755 * @param {boolean} initial True if it comes from setupPath and 862 * @param {boolean} initial True if it comes from setupPath and
756 * false if caused by an user action. 863 * false if caused by an user action.
757 * @param {DirectoryEntry} dirEntry The absolute path to the new directory. 864 * @param {DirectoryEntry} dirEntry The absolute path to the new directory.
758 * @param {function} opt_callback Executed if the directory loads successfully. 865 * @param {function} opt_callback Executed if the directory loads successfully.
759 */ 866 */
760 DirectoryModel.prototype.changeDirectoryEntry_ = function(initial, dirEntry, 867 DirectoryModel.prototype.changeDirectoryEntry_ = function(initial, dirEntry,
761 opt_callback) { 868 opt_callback) {
869 this.clearSearch_();
762 var previous = this.currentDirEntry_; 870 var previous = this.currentDirEntry_;
763 this.currentDirEntry_ = dirEntry; 871 this.currentDirEntry_ = dirEntry;
764 function onRescanComplete() { 872 function onRescanComplete() {
765 if (opt_callback) 873 if (opt_callback)
766 opt_callback(); 874 opt_callback();
767 // For tests that open the dialog to empty directories, everything 875 // For tests that open the dialog to empty directories, everything
768 // is loaded at this point. 876 // is loaded at this point.
769 chrome.test.sendMessage('directory-change-complete'); 877 chrome.test.sendMessage('directory-change-complete');
770 } 878 }
771 this.updateRootsListSelection_(); 879 this.updateRootsListSelection_();
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
1128 /** 1236 /**
1129 * @param {string} path Path 1237 * @param {string} path Path
1130 * @return {boolean} If current directory is system. 1238 * @return {boolean} If current directory is system.
1131 */ 1239 */
1132 DirectoryModel.isSystemDirectory = function(path) { 1240 DirectoryModel.isSystemDirectory = function(path) {
1133 return path == '/' + DirectoryModel.REMOVABLE_DIRECTORY || 1241 return path == '/' + DirectoryModel.REMOVABLE_DIRECTORY ||
1134 path == '/' + DirectoryModel.ARCHIVE_DIRECTORY; 1242 path == '/' + DirectoryModel.ARCHIVE_DIRECTORY;
1135 }; 1243 };
1136 1244
1137 /** 1245 /**
1246 * Performs search and displays results. The search type is dependent on the
1247 * current directory. If we are currently on gdata, server side content search
1248 * over gdata mount point. If the current directory is not on the gdata, file
1249 * name search over current directory wil be performed.
1250 *
1251 * @param {string} query Query that will be searched for.
1252 * @param {function} onSearchRescan Function that will be called when the search
1253 * directory is rescanned (i.e. search results are displayed)
1254 * @param {function} onClearSearch Function to be called when search state gets
1255 * cleared.
1256 */
1257 DirectoryModel.prototype.search = function(query,
1258 onSearchRescan,
1259 onClearSearch) {
1260 if (!query) {
1261 if (this.isSearching_)
1262 this.clearSearch_();
1263 return;
1264 }
1265
1266 this.isSearching_ = true;
1267
1268 // If we alreaqdy have event listener for an old search, we have to remove it.
1269 if (this.onSearchRescan_)
1270 this.removeEventListener('rescan-completed', this.onSearchRescan_);
1271
1272 this.onSearchRescan_ = onSearchRescan;
1273 this.onClearSearch_ = onClearSearch;
1274
1275 this.addEventListener('rescan-completed', this.onSearchRescan_);
1276
1277 // If we are offline, let's fallback to file name search inside dir.
1278 if (this.getRootType() == DirectoryModel.RootType.GDATA &&
1279 !this.isOffline()) {
1280 var self = this;
1281 // Create shadow directory which will contain search results.
1282 this.root_.getDirectory(DirectoryModel.createGDataSearchPath(query),
1283 {create: false},
1284 function(dir) {
1285 self.searchDirEntry_ = dir;
1286 self.rescanSoon();
1287 },
1288 function() {
1289 self.isSearching_ = false;
1290 });
1291 } else {
1292 var queryLC = query.toLowerCase();
1293 this.searchDirEntry_ = this.currentDirEntry_;
1294 this.addFilter(
1295 'searchbox',
1296 function(e) {
1297 return e.name.toLowerCase().indexOf(queryLC) > -1;
1298 });
1299 }
1300 };
1301
1302
1303 /**
1304 * Clears any state set by previous searches.
1305 * @private
1306 */
1307 DirectoryModel.prototype.clearSearch_ = function() {
1308 if (!this.isSearching_)
1309 return;
1310 this.searchDirEntry_ = null;
1311 this.isSearching_ = false;
1312 // This will trigger rescan.
1313 this.removeFilter('searchbox');
1314
1315 if (this.onSearchRescan_) {
1316 this.removeEventListener('rescan-completed', this.onSearchRescan_);
1317 this.onSearchRescan_ = null;
1318 }
1319
1320 if (this.onClearSearch_) {
1321 this.onClearSearch_();
1322 this.onClearSearch_ = null;
1323 }
1324 };
1325
1326 /**
1138 * @param {string} path Any path. 1327 * @param {string} path Any path.
1139 * @return {string} The root path. 1328 * @return {string} The root path.
1140 */ 1329 */
1141 DirectoryModel.getRootPath = function(path) { 1330 DirectoryModel.getRootPath = function(path) {
1142 var type = DirectoryModel.getRootType(path); 1331 var type = DirectoryModel.getRootType(path);
1143 1332
1144 if (type == DirectoryModel.RootType.DOWNLOADS) 1333 if (type == DirectoryModel.RootType.DOWNLOADS)
1145 return '/' + DirectoryModel.DOWNLOADS_DIRECTORY; 1334 return '/' + DirectoryModel.DOWNLOADS_DIRECTORY;
1146 if (type == DirectoryModel.RootType.GDATA) 1335 if (type == DirectoryModel.RootType.GDATA)
1147 return '/' + DirectoryModel.GDATA_DIRECTORY; 1336 return '/' + DirectoryModel.GDATA_DIRECTORY;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1192 * @param {string} path A path. 1381 * @param {string} path A path.
1193 * @return {boolean} True if it is a path to the root. 1382 * @return {boolean} True if it is a path to the root.
1194 */ 1383 */
1195 DirectoryModel.isRootPath = function(path) { 1384 DirectoryModel.isRootPath = function(path) {
1196 if (path[path.length - 1] == '/') 1385 if (path[path.length - 1] == '/')
1197 path = path.substring(0, path.length - 1); 1386 path = path.substring(0, path.length - 1);
1198 return DirectoryModel.getRootPath(path) == path; 1387 return DirectoryModel.getRootPath(path) == path;
1199 }; 1388 };
1200 1389
1201 /** 1390 /**
1391 * Checks if the provided path is under gdata search.
1392 *
1393 * @param {string} path Path to be tested.
1394 * @return {boolean} Is the path gdata search path.
1395 */
1396 DirectoryModel.isGDataSearchPath = function(path) {
1397 return path == DirectoryModel.GDATA_SEARCH_ROOT_PATH ||
1398 path.indexOf(DirectoryModel.GDATA_SEARCH_ROOT_PATH + '/') == 0;
1399 };
1400
1401 /**
1402 * Creates directory path in which gdata content search results for |query|
1403 * should be displayed.
1404 *
1405 * @param {string} query Search query.
1406 * @return {string} Virtual directory path for search results.
1407 */
1408 DirectoryModel.createGDataSearchPath = function(query) {
1409 return DirectoryModel.GDATA_SEARCH_ROOT_PATH + '/' + query;
1410 };
1411
1412 /**
1202 * @constructor 1413 * @constructor
1203 * @extends cr.EventTarget 1414 * @extends cr.EventTarget
1204 * @param {DirectoryEntry} dir Directory to scan. 1415 * @param {DirectoryEntry} dir Directory to scan.
1205 * @param {Array.<Entry>|cr.ui.ArrayDataModel} list Target to put the files. 1416 * @param {Array.<Entry>|cr.ui.ArrayDataModel} list Target to put the files.
1206 * @param {function} successCallback Callback to call when (and if) scan 1417 * @param {function} successCallback Callback to call when (and if) scan
1207 * successfully completed. 1418 * successfully completed.
1208 * @param {function} errorCallback Callback to call in case of IO error. 1419 * @param {function} errorCallback Callback to call in case of IO error.
1209 * @param {function(Array.<Entry>):void, Function)} preprocessChunk 1420 * @param {function(Array.<Entry>):void, Function)} preprocessChunk
1210 * Callback to preprocess each chunk of files. 1421 * Callback to preprocess each chunk of files.
1211 * @param {Object.<string, function(Entry):Boolean>} filters The map of filters 1422 * @param {Object.<string, function(Entry):Boolean>} filters The map of filters
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1288 /** 1499 /**
1289 * @private 1500 * @private
1290 */ 1501 */
1291 DirectoryModel.Scanner.prototype.recordMetrics_ = function() { 1502 DirectoryModel.Scanner.prototype.recordMetrics_ = function() {
1292 metrics.recordInterval('DirectoryScan'); 1503 metrics.recordInterval('DirectoryScan');
1293 if (this.dir_.fullPath == 1504 if (this.dir_.fullPath ==
1294 '/' + DirectoryModel.DOWNLOADS_DIRECTORY) { 1505 '/' + DirectoryModel.DOWNLOADS_DIRECTORY) {
1295 metrics.recordMediumCount('DownloadsCount', this.list_.length); 1506 metrics.recordMediumCount('DownloadsCount', this.list_.length);
1296 } 1507 }
1297 }; 1508 };
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/resources/file_manager/js/file_copy_manager.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698