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 * Directory in which search results are displayed. Not null iff search | |
63 * results are being displayed. | |
64 * @private | |
65 * @type {Entry} | |
66 */ | |
67 this.searchDirEntry_ = null; | |
68 | |
69 /** | |
70 * Is search in progress. | |
71 * @private | |
72 * @type {boolean} | |
73 */ | |
74 this.isSearching_ = false; | |
60 } | 75 } |
61 | 76 |
62 /** | 77 /** |
63 * The name of the directory containing externally | 78 * The name of the directory containing externally |
64 * mounted removable storage volumes. | 79 * mounted removable storage volumes. |
65 */ | 80 */ |
66 DirectoryModel.REMOVABLE_DIRECTORY = 'removable'; | 81 DirectoryModel.REMOVABLE_DIRECTORY = 'removable'; |
67 | 82 |
68 /** | 83 /** |
69 * The name of the directory containing externally | 84 * The name of the directory containing externally |
(...skipping 16 matching lines...) Expand all Loading... | |
86 * The name of the downloads directory. | 101 * The name of the downloads directory. |
87 */ | 102 */ |
88 DirectoryModel.DOWNLOADS_DIRECTORY = 'Downloads'; | 103 DirectoryModel.DOWNLOADS_DIRECTORY = 'Downloads'; |
89 | 104 |
90 /** | 105 /** |
91 * The name of the gdata provider directory. | 106 * The name of the gdata provider directory. |
92 */ | 107 */ |
93 DirectoryModel.GDATA_DIRECTORY = 'gdata'; | 108 DirectoryModel.GDATA_DIRECTORY = 'gdata'; |
94 | 109 |
95 /** | 110 /** |
111 * Root path used for displaying gdata content search results. | |
112 * Search results will be shown in directory 'GDATA_SEARCH_ROOT_PATH/query'. | |
113 * | |
114 * @const | |
115 * @type {string} | |
116 */ | |
117 DirectoryModel.GDATA_SEARCH_ROOT_PATH = '/gdata/.search'; | |
118 | |
119 /** | |
120 * @const | |
121 * @type {Array.<string>} | |
122 */ | |
123 DirectoryModel.GDATA_SEARCH_ROOT_COMPONENTS = ['', 'gdata', '.search']; | |
124 | |
125 /** | |
96 * DirectoryModel extends cr.EventTarget. | 126 * DirectoryModel extends cr.EventTarget. |
97 */ | 127 */ |
98 DirectoryModel.prototype.__proto__ = cr.EventTarget.prototype; | 128 DirectoryModel.prototype.__proto__ = cr.EventTarget.prototype; |
99 | 129 |
100 /** | 130 /** |
101 * @return {cr.ui.ArrayDataModel} Files in the current directory. | 131 * @return {cr.ui.ArrayDataModel} Files in the current directory. |
102 */ | 132 */ |
103 DirectoryModel.prototype.getFileList = function() { | 133 DirectoryModel.prototype.getFileList = function() { |
104 return this.fileList_; | 134 return this.fileList_; |
105 }; | 135 }; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
143 }; | 173 }; |
144 | 174 |
145 /** | 175 /** |
146 * @return {boolean} True if current directory is read only. | 176 * @return {boolean} True if current directory is read only. |
147 */ | 177 */ |
148 DirectoryModel.prototype.isReadOnly = function() { | 178 DirectoryModel.prototype.isReadOnly = function() { |
149 return this.isPathReadOnly(this.getCurrentRootPath()); | 179 return this.isPathReadOnly(this.getCurrentRootPath()); |
150 }; | 180 }; |
151 | 181 |
152 /** | 182 /** |
183 * @return {boolean} True if search is in progress. | |
184 */ | |
185 DirectoryModel.prototype.isSearching = function() { | |
186 return this.isSearching_; | |
187 }; | |
188 | |
189 /** | |
190 * @return {boolean} True if we are currently showing search results. | |
191 */ | |
192 DirectoryModel.prototype.isOnGDataSearchDir = function() { | |
193 return this.getSearchOrCurrentDirEntry() != this.getCurrentDirEntry(); | |
194 }; | |
195 | |
196 /** | |
153 * @param {strin} path Path to check. | 197 * @param {strin} path Path to check. |
154 * @return {boolean} True if the |path| is read only. | 198 * @return {boolean} True if the |path| is read only. |
155 */ | 199 */ |
156 DirectoryModel.prototype.isPathReadOnly = function(path) { | 200 DirectoryModel.prototype.isPathReadOnly = function(path) { |
157 switch (DirectoryModel.getRootType(path)) { | 201 switch (DirectoryModel.getRootType(path)) { |
158 case DirectoryModel.RootType.REMOVABLE: | 202 case DirectoryModel.RootType.REMOVABLE: |
159 return !!this.volumeReadOnlyStatus_[DirectoryModel.getRootPath(path)]; | 203 return !!this.volumeReadOnlyStatus_[DirectoryModel.getRootPath(path)]; |
160 case DirectoryModel.RootType.ARCHIVE: | 204 case DirectoryModel.RootType.ARCHIVE: |
161 return true; | 205 return true; |
162 case DirectoryModel.RootType.DOWNLOADS: | 206 case DirectoryModel.RootType.DOWNLOADS: |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
198 }; | 242 }; |
199 | 243 |
200 /** | 244 /** |
201 * @return {DirectoryEntry} Current directory. | 245 * @return {DirectoryEntry} Current directory. |
202 */ | 246 */ |
203 DirectoryModel.prototype.getCurrentDirEntry = function() { | 247 DirectoryModel.prototype.getCurrentDirEntry = function() { |
204 return this.currentDirEntry_; | 248 return this.currentDirEntry_; |
205 }; | 249 }; |
206 | 250 |
207 /** | 251 /** |
252 * If search results are being displayed, returns search directory, else returns | |
253 * current directory. | |
254 * | |
255 * @return {DirectoryEntry} search or directory entry. | |
256 */ | |
257 DirectoryModel.prototype.getSearchOrCurrentDirEntry = function() { | |
258 return this.searchDirEntry_ || this.currentDirEntry_; | |
259 }; | |
260 | |
261 /** | |
208 * @return {string} Path for the current directory. | 262 * @return {string} Path for the current directory. |
209 */ | 263 */ |
210 DirectoryModel.prototype.getCurrentDirPath = function() { | 264 DirectoryModel.prototype.getCurrentDirPath = function() { |
211 return this.currentDirEntry_.fullPath; | 265 return this.currentDirEntry_.fullPath; |
212 }; | 266 }; |
213 | 267 |
214 /** | 268 /** |
215 * @private | 269 * @private |
216 * @return {Array.<string>} Names of selected files. | 270 * @return {Array.<string>} Names of selected files. |
217 */ | 271 */ |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
402 } | 456 } |
403 } | 457 } |
404 | 458 |
405 function onFailure() { | 459 function onFailure() { |
406 self.scanFailures_++; | 460 self.scanFailures_++; |
407 if (self.scanFailures_ <= 1) | 461 if (self.scanFailures_ <= 1) |
408 self.rescanLater(); | 462 self.rescanLater(); |
409 } | 463 } |
410 | 464 |
411 return new DirectoryModel.Scanner( | 465 return new DirectoryModel.Scanner( |
412 this.currentDirEntry_, | 466 this.getSearchOrCurrentDirEntry(), |
413 list, | 467 list, |
414 onSuccess, | 468 onSuccess, |
415 onFailure, | 469 onFailure, |
416 this.prefetchCacheForSorting_.bind(this), | 470 this.prefetchCacheForSorting_.bind(this), |
417 this.filters_); | 471 this.filters_); |
418 }; | 472 }; |
419 | 473 |
420 /** | 474 /** |
421 * @private | 475 * @private |
422 * @param {Array.<Entry>} entries List of files. | 476 * @param {Array.<Entry>} entries List of files. |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
490 callback) { | 544 callback) { |
491 var field = this.fileList_.sortStatus.field; | 545 var field = this.fileList_.sortStatus.field; |
492 if (field) { | 546 if (field) { |
493 this.prepareSortEntries_(entries, field, callback); | 547 this.prepareSortEntries_(entries, field, callback); |
494 } else { | 548 } else { |
495 callback(); | 549 callback(); |
496 } | 550 } |
497 }; | 551 }; |
498 | 552 |
499 /** | 553 /** |
554 * Gets name that should be displayed in the UI for the entry. | |
555 * @param {string} path Full path of the entry whose display name we are | |
556 * getting. | |
557 * @param {string} defaultName Default name to use if no name is calculated. | |
558 * @return {string} Name to be used for display. | |
559 */ | |
560 DirectoryModel.prototype.getDisplayName = function(path, defaultName) { | |
561 var searchResultName = util.getFileAndDisplayNameForGDataSearchResult(path); | |
562 return searchResultName ? searchResultName.displayName : defaultName; | |
563 }; | |
564 | |
565 /** | |
566 * Creates file name that should be used as a new file name in filesystem | |
567 * 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.
| |
568 * entry, |newName| will be used. | |
dgozman
2012/05/15 11:25:06
typo: newName -> displayName
tbarzic
2012/05/16 03:50:04
Done.
| |
569 * | |
570 * @private | |
571 * @param {Entry} entry Entry which is being renamed. | |
572 * @param {string} displayName The new file name provided by user. | |
573 * @return {string} File name that should be used in renaming filesystem | |
574 * operations. | |
575 */ | |
576 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.
| |
577 // If we are renaming gdata search result, we'll have to format newName to | |
578 // use in file system operation like: <resource_id>.<file_name>. | |
579 var searchResultName = | |
580 util.getFileAndDisplayNameForGDataSearchResult(entry.fullPath); | |
581 return searchResultName ? searchResultName.resourceId + '.' + displayName : | |
582 displayName; | |
583 }; | |
584 | |
585 /** | |
500 * Delete the list of files and directories from filesystem and | 586 * Delete the list of files and directories from filesystem and |
501 * update the file list. | 587 * update the file list. |
502 * @param {Array.<Entry>} entries Entries to delete. | 588 * @param {Array.<Entry>} entries Entries to delete. |
503 * @param {function()=} opt_callback Called when finished. | 589 * @param {function()=} opt_callback Called when finished. |
504 */ | 590 */ |
505 DirectoryModel.prototype.deleteEntries = function(entries, opt_callback) { | 591 DirectoryModel.prototype.deleteEntries = function(entries, opt_callback) { |
506 var downcount = entries.length + 1; | 592 var downcount = entries.length + 1; |
507 | 593 |
508 var onComplete = opt_callback ? function() { | 594 var onComplete = opt_callback ? function() { |
509 if (--downcount == 0) | 595 if (--downcount == 0) |
(...skipping 16 matching lines...) Expand all Loading... | |
526 onSuccess, | 612 onSuccess, |
527 util.flog('Error deleting ' + entry.fullPath, onComplete)); | 613 util.flog('Error deleting ' + entry.fullPath, onComplete)); |
528 } | 614 } |
529 onComplete(); | 615 onComplete(); |
530 }; | 616 }; |
531 | 617 |
532 /** | 618 /** |
533 * @param {string} name Filename. | 619 * @param {string} name Filename. |
534 */ | 620 */ |
535 DirectoryModel.prototype.onEntryChanged = function(name) { | 621 DirectoryModel.prototype.onEntryChanged = function(name) { |
536 var currentEntry = this.currentDirEntry_; | 622 var currentEntry = this.getSearchOrCurrentDirEntry(); |
623 if (currentEntry != this.currentDirEntry_) | |
624 return; | |
537 var dm = this.fileList_; | 625 var dm = this.fileList_; |
538 var self = this; | 626 var self = this; |
539 | 627 |
540 function onEntryFound(entry) { | 628 function onEntryFound(entry) { |
629 // Do nothing if current directory changed during async operations. | |
630 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.
| |
631 return; | |
541 self.prefetchCacheForSorting_([entry], function() { | 632 self.prefetchCacheForSorting_([entry], function() { |
542 // Do nothing if current directory changed during async operations. | 633 // Do nothing if current directory changed during async operations. |
543 if (self.currentDirEntry_ != currentEntry) | 634 if (self.currentDirEntry_ != currentEntry) |
544 return; | 635 return; |
545 | 636 |
546 var index = self.findIndexByName_(name); | 637 var index = self.findIndexByName_(name); |
547 if (index >= 0) | 638 if (index >= 0) |
548 dm.splice(index, 1, entry); | 639 dm.splice(index, 1, entry); |
549 else | 640 else |
550 dm.splice(dm.length, 0, entry); | 641 dm.splice(dm.length, 0, entry); |
551 }); | 642 }); |
552 }; | 643 }; |
553 | 644 |
554 function onError(err) { | 645 function onError(err) { |
555 // Do nothing if current directory changed during async operations. | 646 // Do nothing if current directory changed during async operations. |
556 if (self.currentDirEntry_ != currentEntry) | 647 if (self.currentDirEntry_ != currentEntry) |
557 return; | 648 return; |
558 if (err.code != FileError.NOT_FOUND_ERR) { | 649 if (err.code != FileError.NOT_FOUND_ERR) { |
559 self.rescanLater(); | 650 self.rescanLater(); |
560 return; | 651 return; |
561 } | 652 } |
562 | 653 |
563 var index = self.findIndexByName_(name); | 654 var index = self.findIndexByName_(name); |
564 if (index >= 0) | 655 if (index >= 0) |
565 dm.splice(index, 1); | 656 dm.splice(index, 1); |
566 }; | 657 }; |
567 | 658 |
568 util.resolvePath(this.currentDirEntry_, name, onEntryFound, onError); | 659 util.resolvePath(currentEntry, name, onEntryFound, onError); |
569 }; | 660 }; |
570 | 661 |
571 /** | 662 /** |
572 * @private | 663 * @private |
573 * @param {string} name Filename. | 664 * @param {string} name Filename. |
574 * @return {number} The index in the fileList. | 665 * @return {number} The index in the fileList. |
575 */ | 666 */ |
576 DirectoryModel.prototype.findIndexByName_ = function(name) { | 667 DirectoryModel.prototype.findIndexByName_ = function(name) { |
577 var dm = this.fileList_; | 668 var dm = this.fileList_; |
578 for (var i = 0; i < dm.length; i++) | 669 for (var i = 0; i < dm.length; i++) |
579 if (dm.item(i).name == name) | 670 if (dm.item(i).name == name) |
580 return i; | 671 return i; |
581 return -1; | 672 return -1; |
582 }; | 673 }; |
583 | 674 |
584 /** | 675 /** |
585 * Rename the entry in the filesystem and update the file list. | 676 * Rename the entry in the filesystem and update the file list. |
586 * @param {Entry} entry Entry to rename. | 677 * @param {Entry} entry Entry to rename. |
587 * @param {string} newName New name. | 678 * @param {string} newDisplayName New name. |
588 * @param {function} errorCallback Called on error. | 679 * @param {function} errorCallback Called on error. |
589 * @param {function} opt_successCallback Called on success. | 680 * @param {function} opt_successCallback Called on success. |
590 */ | 681 */ |
591 DirectoryModel.prototype.renameEntry = function(entry, newName, errorCallback, | 682 DirectoryModel.prototype.renameEntry = function(entry, newDisplayName, |
683 errorCallback, | |
592 opt_successCallback) { | 684 opt_successCallback) { |
593 var self = this; | 685 var self = this; |
594 function onSuccess(newEntry) { | 686 function onSuccess(newEntry) { |
595 self.prefetchCacheForSorting_([newEntry], function() { | 687 self.prefetchCacheForSorting_([newEntry], function() { |
596 var fileList = self.fileList_; | 688 var fileList = self.fileList_; |
597 var index = fileList.indexOf(entry); | 689 var index = fileList.indexOf(entry); |
598 if (index >= 0) | 690 if (index >= 0) |
599 fileList.splice(index, 1, newEntry); | 691 fileList.splice(index, 1, newEntry); |
600 self.selectEntry(newName); | 692 self.selectEntry(newEntry.name); |
601 // If the entry doesn't exist in the list it mean that it updated from | 693 // If the entry doesn't exist in the list it mean that it updated from |
602 // outside (probably by directory rescan). | 694 // outside (probably by directory rescan). |
603 if (opt_successCallback) | 695 if (opt_successCallback) |
604 opt_successCallback(); | 696 opt_successCallback(); |
605 }); | 697 }); |
606 } | 698 } |
607 entry.moveTo(this.currentDirEntry_, newName, onSuccess, errorCallback); | 699 |
700 var newEntryName = this.getEntryName_(entry, newDisplayName); | |
701 entry.moveTo(this.getSearchOrCurrentDirEntry(), newEntryName, onSuccess, | |
702 errorCallback); | |
608 }; | 703 }; |
609 | 704 |
610 /** | 705 /** |
611 * Checks if current directory contains a file or directory with this name. | 706 * Checks if current directory contains a file or directory with this name. |
612 * @param {string} newName Name to check. | 707 * @param {string} entry Entry to which newName will be given. |
708 * @param {string} displayName Name to check. | |
613 * @param {function(boolean, boolean?)} callback Called when the result's | 709 * @param {function(boolean, boolean?)} callback Called when the result's |
614 * available. First parameter is true if the entry exists and second | 710 * available. First parameter is true if the entry exists and second |
615 * is true if it's a file. | 711 * is true if it's a file. |
616 */ | 712 */ |
617 DirectoryModel.prototype.doesExist = function(newName, callback) { | 713 DirectoryModel.prototype.doesExist = function(entry, displayName, callback) { |
618 util.resolvePath(this.currentDirEntry_, newName, | 714 var entryName = this.getEntryName_(entry, displayName); |
715 | |
716 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
| |
619 function(entry) { | 717 function(entry) { |
620 callback(true, entry.isFile); | 718 callback(true, entry.isFile); |
621 }, | 719 }, |
622 callback.bind(window, false)); | 720 callback.bind(window, false)); |
623 }; | 721 }; |
624 | 722 |
625 /** | 723 /** |
626 * Creates directory and updates the file list. | 724 * Creates directory and updates the file list. |
627 * | 725 * |
628 * @param {string} name Directory name. | 726 * @param {string} name Directory name. |
(...skipping 25 matching lines...) Expand all Loading... | |
654 this.currentDirEntry_.getDirectory(name, {create: true, exclusive: true}, | 752 this.currentDirEntry_.getDirectory(name, {create: true, exclusive: true}, |
655 onSuccess, errorCallback); | 753 onSuccess, errorCallback); |
656 }; | 754 }; |
657 | 755 |
658 /** | 756 /** |
659 * Changes directory. Causes 'directory-change' event. | 757 * Changes directory. Causes 'directory-change' event. |
660 * | 758 * |
661 * @param {string} path New current directory path. | 759 * @param {string} path New current directory path. |
662 */ | 760 */ |
663 DirectoryModel.prototype.changeDirectory = function(path) { | 761 DirectoryModel.prototype.changeDirectory = function(path) { |
664 this.resolveDirectory(path, function(directoryEntry) { | 762 var targetPath = path; |
763 // We should not be changing directory to gdata search path. If we do, default | |
764 // to gdata root. | |
765 if (DirectoryModel.isGDataSearchPath(path)) { | |
766 console.error('Attempt to change directory to search path.'); | |
767 targetPath = '/' + DirectoryModel.GDATA_DIRECTORY; | |
768 } | |
769 | |
770 this.resolveDirectory(targetPath, function(directoryEntry) { | |
665 this.changeDirectoryEntry_(false, directoryEntry); | 771 this.changeDirectoryEntry_(false, directoryEntry); |
666 }.bind(this), function(error) { | 772 }.bind(this), function(error) { |
667 console.error('Error changing directory to ' + path + ': ', error); | 773 console.error('Error changing directory to ' + path + ': ', error); |
668 }); | 774 }); |
669 }; | 775 }; |
670 | 776 |
671 /** | 777 /** |
672 * Resolves absolute directory path. Handles GData stub. | 778 * Resolves absolute directory path. Handles GData stub. |
673 * @param {string} path Path to the directory. | 779 * @param {string} path Path to the directory. |
674 * @param {function(DirectoryEntry} successCallback Success callback. | 780 * @param {function(DirectoryEntry} successCallback Success callback. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
724 * changed. | 830 * changed. |
725 * | 831 * |
726 * @private | 832 * @private |
727 * @param {boolean} initial True if it comes from setupPath and | 833 * @param {boolean} initial True if it comes from setupPath and |
728 * false if caused by an user action. | 834 * false if caused by an user action. |
729 * @param {DirectoryEntry} dirEntry The absolute path to the new directory. | 835 * @param {DirectoryEntry} dirEntry The absolute path to the new directory. |
730 * @param {function} opt_callback Executed if the directory loads successfully. | 836 * @param {function} opt_callback Executed if the directory loads successfully. |
731 */ | 837 */ |
732 DirectoryModel.prototype.changeDirectoryEntry_ = function(initial, dirEntry, | 838 DirectoryModel.prototype.changeDirectoryEntry_ = function(initial, dirEntry, |
733 opt_callback) { | 839 opt_callback) { |
840 this.clearSearch_(); | |
734 var previous = this.currentDirEntry_; | 841 var previous = this.currentDirEntry_; |
735 this.currentDirEntry_ = dirEntry; | 842 this.currentDirEntry_ = dirEntry; |
736 function onRescanComplete() { | 843 function onRescanComplete() { |
737 if (opt_callback) | 844 if (opt_callback) |
738 opt_callback(); | 845 opt_callback(); |
739 // For tests that open the dialog to empty directories, everything | 846 // For tests that open the dialog to empty directories, everything |
740 // is loaded at this point. | 847 // is loaded at this point. |
741 chrome.test.sendMessage('directory-change-complete'); | 848 chrome.test.sendMessage('directory-change-complete'); |
742 } | 849 } |
743 this.updateRootsListSelection_(); | 850 this.updateRootsListSelection_(); |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1102 // Re-place the entry into the roots data model to force re-rendering. | 1209 // Re-place the entry into the roots data model to force re-rendering. |
1103 this.rootsList_.splice(index, 1, entry); | 1210 this.rootsList_.splice(index, 1, entry); |
1104 | 1211 |
1105 if (rootPath == this.rootPath) { | 1212 if (rootPath == this.rootPath) { |
1106 // TODO(kaznacheev): Consider changing to the most recently used root. | 1213 // TODO(kaznacheev): Consider changing to the most recently used root. |
1107 this.changeDirectory(this.getDefaultDirectory()); | 1214 this.changeDirectory(this.getDefaultDirectory()); |
1108 } | 1215 } |
1109 }; | 1216 }; |
1110 | 1217 |
1111 /** | 1218 /** |
1219 * Performs search and displays results. The search type is dependent on the | |
1220 * current directory. If we are currently on gdata, server side content search | |
1221 * over gdata mount point. If the current directory is not on the gdata, file | |
1222 * name search over current directory wil be performed. | |
1223 * | |
1224 * @param {string} query Query that will be searched for. | |
1225 */ | |
1226 DirectoryModel.prototype.search = function(query) { | |
1227 if (!query) { | |
1228 this.clearSearch_(); | |
1229 return; | |
1230 } | |
1231 | |
1232 this.isSearching_ = true; | |
1233 | |
1234 // If we are offline, let's fallback to file name search inside dir. | |
1235 if (this.getRootType() == DirectoryModel.RootType.GDATA && | |
1236 !util.isOffline()) { | |
1237 var self = this; | |
1238 // 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.
| |
1239 this.root_.getDirectory(DirectoryModel.createGDataSearchPath(query), | |
1240 {create: false}, | |
1241 function(dir) { | |
1242 self.searchDirEntry_ = dir; | |
1243 self.rescanSoon(); | |
1244 }, | |
1245 this.clearSearch_.bind(this)); | |
1246 } else { | |
1247 this.searchDirEntry_ = this.currentDirEntry_; | |
1248 this.addFilter( | |
1249 'searchbox', | |
1250 function(e) { | |
1251 return e.name.substring(0, query.length) == query; | |
1252 }); | |
1253 } | |
1254 }; | |
1255 | |
1256 | |
1257 /** | |
1258 * Clears any state set by previous searches. | |
1259 * @private | |
1260 */ | |
1261 DirectoryModel.prototype.clearSearch_ = function() { | |
1262 this.searchDirEntry_ = null; | |
1263 this.isSearching_ = false; | |
1264 // This will trigger rescan. | |
1265 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
| |
1266 }; | |
1267 | |
1268 /** | |
1112 * @param {string} path Any path. | 1269 * @param {string} path Any path. |
1113 * @return {string} The root path. | 1270 * @return {string} The root path. |
1114 */ | 1271 */ |
1115 DirectoryModel.getRootPath = function(path) { | 1272 DirectoryModel.getRootPath = function(path) { |
1116 var type = DirectoryModel.getRootType(path); | 1273 var type = DirectoryModel.getRootType(path); |
1117 | 1274 |
1118 if (type == DirectoryModel.RootType.DOWNLOADS) | 1275 if (type == DirectoryModel.RootType.DOWNLOADS) |
1119 return '/' + DirectoryModel.DOWNLOADS_DIRECTORY; | 1276 return '/' + DirectoryModel.DOWNLOADS_DIRECTORY; |
1120 if (type == DirectoryModel.RootType.GDATA) | 1277 if (type == DirectoryModel.RootType.GDATA) |
1121 return '/' + DirectoryModel.GDATA_DIRECTORY; | 1278 return '/' + DirectoryModel.GDATA_DIRECTORY; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1166 * @param {string} path A path. | 1323 * @param {string} path A path. |
1167 * @return {boolean} True if it is a path to the root. | 1324 * @return {boolean} True if it is a path to the root. |
1168 */ | 1325 */ |
1169 DirectoryModel.isRootPath = function(path) { | 1326 DirectoryModel.isRootPath = function(path) { |
1170 if (path[path.length - 1] == '/') | 1327 if (path[path.length - 1] == '/') |
1171 path = path.substring(0, path.length - 1); | 1328 path = path.substring(0, path.length - 1); |
1172 return DirectoryModel.getRootPath(path) == path; | 1329 return DirectoryModel.getRootPath(path) == path; |
1173 }; | 1330 }; |
1174 | 1331 |
1175 /** | 1332 /** |
1333 * Checks if the provided path is under gdata search. | |
1334 * | |
1335 * @param {string} path Path to be tested. | |
1336 * @return {boolean} Is the path gdata search path. | |
1337 */ | |
1338 DirectoryModel.isGDataSearchPath = function(path) { | |
1339 return path == DirectoryModel.GDATA_SEARCH_ROOT_PATH || | |
1340 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.
| |
1341 }; | |
1342 | |
1343 /** | |
1344 * Creates directory path in which gdata content search results for |query| | |
1345 * should be displayed. | |
1346 * | |
1347 * @param {string} query Search query. | |
1348 * @return {string} Virtual directory path for search results. | |
1349 */ | |
1350 DirectoryModel.createGDataSearchPath = function(query) { | |
1351 return DirectoryModel.GDATA_SEARCH_ROOT_PATH + '/' + query; | |
1352 }; | |
1353 | |
1354 /** | |
1176 * @constructor | 1355 * @constructor |
1177 * @extends cr.EventTarget | 1356 * @extends cr.EventTarget |
1178 * @param {DirectoryEntry} dir Directory to scan. | 1357 * @param {DirectoryEntry} dir Directory to scan. |
1179 * @param {Array.<Entry>|cr.ui.ArrayDataModel} list Target to put the files. | 1358 * @param {Array.<Entry>|cr.ui.ArrayDataModel} list Target to put the files. |
1180 * @param {function} successCallback Callback to call when (and if) scan | 1359 * @param {function} successCallback Callback to call when (and if) scan |
1181 * successfully completed. | 1360 * successfully completed. |
1182 * @param {function} errorCallback Callback to call in case of IO error. | 1361 * @param {function} errorCallback Callback to call in case of IO error. |
1183 * @param {function(Array.<Entry>):void, Function)} preprocessChunk | 1362 * @param {function(Array.<Entry>):void, Function)} preprocessChunk |
1184 * Callback to preprocess each chunk of files. | 1363 * Callback to preprocess each chunk of files. |
1185 * @param {Object.<string, function(Entry):Boolean>} filters The map of filters | 1364 * @param {Object.<string, function(Entry):Boolean>} filters The map of filters |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1262 /** | 1441 /** |
1263 * @private | 1442 * @private |
1264 */ | 1443 */ |
1265 DirectoryModel.Scanner.prototype.recordMetrics_ = function() { | 1444 DirectoryModel.Scanner.prototype.recordMetrics_ = function() { |
1266 metrics.recordInterval('DirectoryScan'); | 1445 metrics.recordInterval('DirectoryScan'); |
1267 if (this.dir_.fullPath == | 1446 if (this.dir_.fullPath == |
1268 '/' + DirectoryModel.DOWNLOADS_DIRECTORY) { | 1447 '/' + DirectoryModel.DOWNLOADS_DIRECTORY) { |
1269 metrics.recordMediumCount('DownloadsCount', this.list_.length); | 1448 metrics.recordMediumCount('DownloadsCount', this.list_.length); |
1270 } | 1449 } |
1271 }; | 1450 }; |
OLD | NEW |