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 /** |
153 * @param {strin} path Path to check. | 190 * @param {strin} path Path to check. |
154 * @return {boolean} True if the |path| is read only. | 191 * @return {boolean} True if the |path| is read only. |
155 */ | 192 */ |
156 DirectoryModel.prototype.isPathReadOnly = function(path) { | 193 DirectoryModel.prototype.isPathReadOnly = function(path) { |
157 switch (DirectoryModel.getRootType(path)) { | 194 switch (DirectoryModel.getRootType(path)) { |
158 case DirectoryModel.RootType.REMOVABLE: | 195 case DirectoryModel.RootType.REMOVABLE: |
159 return !!this.volumeReadOnlyStatus_[DirectoryModel.getRootPath(path)]; | 196 return !!this.volumeReadOnlyStatus_[DirectoryModel.getRootPath(path)]; |
160 case DirectoryModel.RootType.ARCHIVE: | 197 case DirectoryModel.RootType.ARCHIVE: |
161 return true; | 198 return true; |
162 case DirectoryModel.RootType.DOWNLOADS: | 199 case DirectoryModel.RootType.DOWNLOADS: |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 }; | 235 }; |
199 | 236 |
200 /** | 237 /** |
201 * @return {DirectoryEntry} Current directory. | 238 * @return {DirectoryEntry} Current directory. |
202 */ | 239 */ |
203 DirectoryModel.prototype.getCurrentDirEntry = function() { | 240 DirectoryModel.prototype.getCurrentDirEntry = function() { |
204 return this.currentDirEntry_; | 241 return this.currentDirEntry_; |
205 }; | 242 }; |
206 | 243 |
207 /** | 244 /** |
| 245 * If search results are being displayed, returns search directory, else returns |
| 246 * current directory. |
| 247 * |
| 248 * @return {DirectoryEntry} search or directory entry. |
| 249 */ |
| 250 DirectoryModel.prototype.getSearchOrCurrentDirEntry = function() { |
| 251 return this.searchDirEntry_ || this.currentDirEntry_; |
| 252 }; |
| 253 |
| 254 /** |
208 * @return {string} Path for the current directory. | 255 * @return {string} Path for the current directory. |
209 */ | 256 */ |
210 DirectoryModel.prototype.getCurrentDirPath = function() { | 257 DirectoryModel.prototype.getCurrentDirPath = function() { |
211 return this.currentDirEntry_.fullPath; | 258 return this.currentDirEntry_.fullPath; |
212 }; | 259 }; |
213 | 260 |
214 /** | 261 /** |
215 * @private | 262 * @private |
216 * @return {Array.<string>} Names of selected files. | 263 * @return {Array.<string>} Names of selected files. |
217 */ | 264 */ |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 } | 449 } |
403 } | 450 } |
404 | 451 |
405 function onFailure() { | 452 function onFailure() { |
406 self.scanFailures_++; | 453 self.scanFailures_++; |
407 if (self.scanFailures_ <= 1) | 454 if (self.scanFailures_ <= 1) |
408 self.rescanLater(); | 455 self.rescanLater(); |
409 } | 456 } |
410 | 457 |
411 return new DirectoryModel.Scanner( | 458 return new DirectoryModel.Scanner( |
412 this.currentDirEntry_, | 459 this.getSearchOrCurrentDirEntry(), |
413 list, | 460 list, |
414 onSuccess, | 461 onSuccess, |
415 onFailure, | 462 onFailure, |
416 this.prefetchCacheForSorting_.bind(this), | 463 this.prefetchCacheForSorting_.bind(this), |
417 this.filters_); | 464 this.filters_); |
418 }; | 465 }; |
419 | 466 |
420 /** | 467 /** |
421 * @private | 468 * @private |
422 * @param {Array.<Entry>} entries List of files. | 469 * @param {Array.<Entry>} entries List of files. |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 callback) { | 537 callback) { |
491 var field = this.fileList_.sortStatus.field; | 538 var field = this.fileList_.sortStatus.field; |
492 if (field) { | 539 if (field) { |
493 this.prepareSortEntries_(entries, field, callback); | 540 this.prepareSortEntries_(entries, field, callback); |
494 } else { | 541 } else { |
495 callback(); | 542 callback(); |
496 } | 543 } |
497 }; | 544 }; |
498 | 545 |
499 /** | 546 /** |
| 547 * Gets name that should be displayed in the UI for the entry. |
| 548 * @param {string} path Full path of the entry whose display name we are |
| 549 * getting. |
| 550 * @param {string} defaultName Default name to use if no name is calculated. |
| 551 * @return {string} Name to be used for display. |
| 552 */ |
| 553 DirectoryModel.prototype.getDisplayName = function(path, defaultName) { |
| 554 var searchResultName = util.getFileAndDisplayNameForGDataSearchResult(path); |
| 555 return searchResultName ? searchResultName.displayName : defaultName; |
| 556 }; |
| 557 |
| 558 /** |
| 559 * Creates file name that should be used as a new file name in filesystem |
| 560 * operations while renaming. It the given entry is not a gdata search result |
| 561 * entry, |newName| will be used. |
| 562 * |
| 563 * @private |
| 564 * @param {Entry} entry Entry which is being renamed. |
| 565 * @param {string} displayName The new file name provided by user. |
| 566 * @return {string} File name that should be used in renaming filesystem |
| 567 * operations. |
| 568 */ |
| 569 DirectoryModel.prototype.getEntryName_ = function(entry, displayName) { |
| 570 // If we are renaming gdata search result, we'll have to format newName to |
| 571 // use in file system operation like: <resource_id>.<file_name>. |
| 572 var searchResultName = |
| 573 util.getFileAndDisplayNameForGDataSearchResult(entry.fullPath); |
| 574 return searchResultName ? searchResultName.resourceId + '.' + displayName : |
| 575 displayName; |
| 576 }; |
| 577 |
| 578 /** |
500 * Delete the list of files and directories from filesystem and | 579 * Delete the list of files and directories from filesystem and |
501 * update the file list. | 580 * update the file list. |
502 * @param {Array.<Entry>} entries Entries to delete. | 581 * @param {Array.<Entry>} entries Entries to delete. |
503 * @param {function()=} opt_callback Called when finished. | 582 * @param {function()=} opt_callback Called when finished. |
504 */ | 583 */ |
505 DirectoryModel.prototype.deleteEntries = function(entries, opt_callback) { | 584 DirectoryModel.prototype.deleteEntries = function(entries, opt_callback) { |
506 var downcount = entries.length + 1; | 585 var downcount = entries.length + 1; |
507 | 586 |
508 var onComplete = opt_callback ? function() { | 587 var onComplete = opt_callback ? function() { |
509 if (--downcount == 0) | 588 if (--downcount == 0) |
(...skipping 16 matching lines...) Expand all Loading... |
526 onSuccess, | 605 onSuccess, |
527 util.flog('Error deleting ' + entry.fullPath, onComplete)); | 606 util.flog('Error deleting ' + entry.fullPath, onComplete)); |
528 } | 607 } |
529 onComplete(); | 608 onComplete(); |
530 }; | 609 }; |
531 | 610 |
532 /** | 611 /** |
533 * @param {string} name Filename. | 612 * @param {string} name Filename. |
534 */ | 613 */ |
535 DirectoryModel.prototype.onEntryChanged = function(name) { | 614 DirectoryModel.prototype.onEntryChanged = function(name) { |
536 var currentEntry = this.currentDirEntry_; | 615 var currentEntry = this.getSearchOrCurrentDirEntry(); |
| 616 if (currentEntry != this.currentDirEntry_) |
| 617 return; |
537 var dm = this.fileList_; | 618 var dm = this.fileList_; |
538 var self = this; | 619 var self = this; |
539 | 620 |
540 function onEntryFound(entry) { | 621 function onEntryFound(entry) { |
| 622 // Do nothing if current directory changed during async operations. |
| 623 if (self.currentDirEntry_ != currentEntry) |
| 624 return; |
541 self.prefetchCacheForSorting_([entry], function() { | 625 self.prefetchCacheForSorting_([entry], function() { |
542 // Do nothing if current directory changed during async operations. | 626 // Do nothing if current directory changed during async operations. |
543 if (self.currentDirEntry_ != currentEntry) | 627 if (self.currentDirEntry_ != currentEntry) |
544 return; | 628 return; |
545 | 629 |
546 var index = self.findIndexByName_(name); | 630 var index = self.findIndexByName_(name); |
547 if (index >= 0) | 631 if (index >= 0) |
548 dm.splice(index, 1, entry); | 632 dm.splice(index, 1, entry); |
549 else | 633 else |
550 dm.splice(dm.length, 0, entry); | 634 dm.splice(dm.length, 0, entry); |
551 }); | 635 }); |
552 }; | 636 }; |
553 | 637 |
554 function onError(err) { | 638 function onError(err) { |
555 // Do nothing if current directory changed during async operations. | 639 // Do nothing if current directory changed during async operations. |
556 if (self.currentDirEntry_ != currentEntry) | 640 if (self.currentDirEntry_ != currentEntry) |
557 return; | 641 return; |
558 if (err.code != FileError.NOT_FOUND_ERR) { | 642 if (err.code != FileError.NOT_FOUND_ERR) { |
559 self.rescanLater(); | 643 self.rescanLater(); |
560 return; | 644 return; |
561 } | 645 } |
562 | 646 |
563 var index = self.findIndexByName_(name); | 647 var index = self.findIndexByName_(name); |
564 if (index >= 0) | 648 if (index >= 0) |
565 dm.splice(index, 1); | 649 dm.splice(index, 1); |
566 }; | 650 }; |
567 | 651 |
568 util.resolvePath(this.currentDirEntry_, name, onEntryFound, onError); | 652 util.resolvePath(currentEntry, name, onEntryFound, onError); |
569 }; | 653 }; |
570 | 654 |
571 /** | 655 /** |
572 * @private | 656 * @private |
573 * @param {string} name Filename. | 657 * @param {string} name Filename. |
574 * @return {number} The index in the fileList. | 658 * @return {number} The index in the fileList. |
575 */ | 659 */ |
576 DirectoryModel.prototype.findIndexByName_ = function(name) { | 660 DirectoryModel.prototype.findIndexByName_ = function(name) { |
577 var dm = this.fileList_; | 661 var dm = this.fileList_; |
578 for (var i = 0; i < dm.length; i++) | 662 for (var i = 0; i < dm.length; i++) |
579 if (dm.item(i).name == name) | 663 if (dm.item(i).name == name) |
580 return i; | 664 return i; |
581 return -1; | 665 return -1; |
582 }; | 666 }; |
583 | 667 |
584 /** | 668 /** |
585 * Rename the entry in the filesystem and update the file list. | 669 * Rename the entry in the filesystem and update the file list. |
586 * @param {Entry} entry Entry to rename. | 670 * @param {Entry} entry Entry to rename. |
587 * @param {string} newName New name. | 671 * @param {string} newDisplayName New name. |
588 * @param {function} errorCallback Called on error. | 672 * @param {function} errorCallback Called on error. |
589 * @param {function} opt_successCallback Called on success. | 673 * @param {function} opt_successCallback Called on success. |
590 */ | 674 */ |
591 DirectoryModel.prototype.renameEntry = function(entry, newName, errorCallback, | 675 DirectoryModel.prototype.renameEntry = function(entry, newDisplayName, |
| 676 errorCallback, |
592 opt_successCallback) { | 677 opt_successCallback) { |
593 var self = this; | 678 var self = this; |
594 function onSuccess(newEntry) { | 679 function onSuccess(newEntry) { |
595 self.prefetchCacheForSorting_([newEntry], function() { | 680 self.prefetchCacheForSorting_([newEntry], function() { |
596 var fileList = self.fileList_; | 681 var fileList = self.fileList_; |
597 var index = fileList.indexOf(entry); | 682 var index = fileList.indexOf(entry); |
598 if (index >= 0) | 683 if (index >= 0) |
599 fileList.splice(index, 1, newEntry); | 684 fileList.splice(index, 1, newEntry); |
600 self.selectEntry(newName); | 685 self.selectEntry(newEntry.name); |
601 // If the entry doesn't exist in the list it mean that it updated from | 686 // If the entry doesn't exist in the list it mean that it updated from |
602 // outside (probably by directory rescan). | 687 // outside (probably by directory rescan). |
603 if (opt_successCallback) | 688 if (opt_successCallback) |
604 opt_successCallback(); | 689 opt_successCallback(); |
605 }); | 690 }); |
606 } | 691 } |
607 entry.moveTo(this.currentDirEntry_, newName, onSuccess, errorCallback); | 692 |
| 693 var newEntryName = this.getEntryName_(entry, newDisplayName); |
| 694 entry.moveTo(this.getSearchOrCurrentDirEntry(), newEntryName, onSuccess, |
| 695 errorCallback); |
608 }; | 696 }; |
609 | 697 |
610 /** | 698 /** |
611 * Checks if current directory contains a file or directory with this name. | 699 * Checks if current directory contains a file or directory with this name. |
612 * @param {string} newName Name to check. | 700 * @param {string} entry Entry to which newName will be given. |
| 701 * @param {string} displayName Name to check. |
613 * @param {function(boolean, boolean?)} callback Called when the result's | 702 * @param {function(boolean, boolean?)} callback Called when the result's |
614 * available. First parameter is true if the entry exists and second | 703 * available. First parameter is true if the entry exists and second |
615 * is true if it's a file. | 704 * is true if it's a file. |
616 */ | 705 */ |
617 DirectoryModel.prototype.doesExist = function(newName, callback) { | 706 DirectoryModel.prototype.doesExist = function(entry, displayName, callback) { |
618 util.resolvePath(this.currentDirEntry_, newName, | 707 var entryName = this.getEntryName_(entry, displayName); |
| 708 |
| 709 util.resolvePath(this.getSearchOrCurrentDirEntry(), entryName, |
619 function(entry) { | 710 function(entry) { |
620 callback(true, entry.isFile); | 711 callback(true, entry.isFile); |
621 }, | 712 }, |
622 callback.bind(window, false)); | 713 callback.bind(window, false)); |
623 }; | 714 }; |
624 | 715 |
625 /** | 716 /** |
626 * Creates directory and updates the file list. | 717 * Creates directory and updates the file list. |
627 * | 718 * |
628 * @param {string} name Directory name. | 719 * @param {string} name Directory name. |
(...skipping 25 matching lines...) Expand all Loading... |
654 this.currentDirEntry_.getDirectory(name, {create: true, exclusive: true}, | 745 this.currentDirEntry_.getDirectory(name, {create: true, exclusive: true}, |
655 onSuccess, errorCallback); | 746 onSuccess, errorCallback); |
656 }; | 747 }; |
657 | 748 |
658 /** | 749 /** |
659 * Changes directory. Causes 'directory-change' event. | 750 * Changes directory. Causes 'directory-change' event. |
660 * | 751 * |
661 * @param {string} path New current directory path. | 752 * @param {string} path New current directory path. |
662 */ | 753 */ |
663 DirectoryModel.prototype.changeDirectory = function(path) { | 754 DirectoryModel.prototype.changeDirectory = function(path) { |
664 this.resolveDirectory(path, function(directoryEntry) { | 755 var targetPath = path; |
| 756 // We should not be changing directory to gdata search path. If we do, default |
| 757 // to gdata root. |
| 758 if (DirectoryModel.isGDataSearchPath(path)) { |
| 759 console.error('Attempt to change directory to search path.'); |
| 760 targetPath = '/' + DirectoryModel.GDATA_DIRECTORY; |
| 761 } |
| 762 |
| 763 this.resolveDirectory(targetPath, function(directoryEntry) { |
665 this.changeDirectoryEntry_(false, directoryEntry); | 764 this.changeDirectoryEntry_(false, directoryEntry); |
666 }.bind(this), function(error) { | 765 }.bind(this), function(error) { |
667 console.error('Error changing directory to ' + path + ': ', error); | 766 console.error('Error changing directory to ' + path + ': ', error); |
668 }); | 767 }); |
669 }; | 768 }; |
670 | 769 |
671 /** | 770 /** |
672 * Resolves absolute directory path. Handles GData stub. | 771 * Resolves absolute directory path. Handles GData stub. |
673 * @param {string} path Path to the directory. | 772 * @param {string} path Path to the directory. |
674 * @param {function(DirectoryEntry} successCallback Success callback. | 773 * @param {function(DirectoryEntry} successCallback Success callback. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 * changed. | 823 * changed. |
725 * | 824 * |
726 * @private | 825 * @private |
727 * @param {boolean} initial True if it comes from setupPath and | 826 * @param {boolean} initial True if it comes from setupPath and |
728 * false if caused by an user action. | 827 * false if caused by an user action. |
729 * @param {DirectoryEntry} dirEntry The absolute path to the new directory. | 828 * @param {DirectoryEntry} dirEntry The absolute path to the new directory. |
730 * @param {function} opt_callback Executed if the directory loads successfully. | 829 * @param {function} opt_callback Executed if the directory loads successfully. |
731 */ | 830 */ |
732 DirectoryModel.prototype.changeDirectoryEntry_ = function(initial, dirEntry, | 831 DirectoryModel.prototype.changeDirectoryEntry_ = function(initial, dirEntry, |
733 opt_callback) { | 832 opt_callback) { |
| 833 this.clearSearch_(); |
734 var previous = this.currentDirEntry_; | 834 var previous = this.currentDirEntry_; |
735 this.currentDirEntry_ = dirEntry; | 835 this.currentDirEntry_ = dirEntry; |
736 function onRescanComplete() { | 836 function onRescanComplete() { |
737 if (opt_callback) | 837 if (opt_callback) |
738 opt_callback(); | 838 opt_callback(); |
739 // For tests that open the dialog to empty directories, everything | 839 // For tests that open the dialog to empty directories, everything |
740 // is loaded at this point. | 840 // is loaded at this point. |
741 chrome.test.sendMessage('directory-change-complete'); | 841 chrome.test.sendMessage('directory-change-complete'); |
742 } | 842 } |
743 this.updateRootsListSelection_(); | 843 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. | 1202 // Re-place the entry into the roots data model to force re-rendering. |
1103 this.rootsList_.splice(index, 1, entry); | 1203 this.rootsList_.splice(index, 1, entry); |
1104 | 1204 |
1105 if (rootPath == this.rootPath) { | 1205 if (rootPath == this.rootPath) { |
1106 // TODO(kaznacheev): Consider changing to the most recently used root. | 1206 // TODO(kaznacheev): Consider changing to the most recently used root. |
1107 this.changeDirectory(this.getDefaultDirectory()); | 1207 this.changeDirectory(this.getDefaultDirectory()); |
1108 } | 1208 } |
1109 }; | 1209 }; |
1110 | 1210 |
1111 /** | 1211 /** |
| 1212 * Performs search and displays results. The search type is dependent on the |
| 1213 * current directory. If we are currently on gdata, server side content search |
| 1214 * over gdata mount point. If the current directory is not on the gdata, file |
| 1215 * name search over current directory wil be performed. |
| 1216 * |
| 1217 * @param {string} query Query that will be searched for. |
| 1218 */ |
| 1219 DirectoryModel.prototype.search = function(query) { |
| 1220 if (!query) { |
| 1221 this.clearSearch_(); |
| 1222 return; |
| 1223 } |
| 1224 |
| 1225 this.isSearching_ = true; |
| 1226 |
| 1227 // If we are offline, let's fallback to file name search inside dir. |
| 1228 if (this.getRootType() == DirectoryModel.RootType.GDATA && |
| 1229 !util.isOffline()) { |
| 1230 var self = this; |
| 1231 // Create shadow directory which will contein search results. |
| 1232 this.root_.getDirectory(DirectoryModel.createGDataSearchPath(query), |
| 1233 {create: false}, |
| 1234 function(dir) { |
| 1235 self.searchDirEntry_ = dir; |
| 1236 self.rescanSoon(); |
| 1237 }); |
| 1238 } else { |
| 1239 this.searchDirEntry_ = this.currentDirEntry_; |
| 1240 this.addFilter( |
| 1241 'searchbox', |
| 1242 function(e) { |
| 1243 return e.name.substring(0, query.length) == query; |
| 1244 }); |
| 1245 } |
| 1246 }; |
| 1247 |
| 1248 |
| 1249 /** |
| 1250 * Clears any state set by previous searches. |
| 1251 * @private |
| 1252 */ |
| 1253 DirectoryModel.prototype.clearSearch_ = function() { |
| 1254 this.searchDirEntry_ = null; |
| 1255 this.isSearching_ = false; |
| 1256 // This will trigger rescan. |
| 1257 this.removeFilter('searchbox'); |
| 1258 }; |
| 1259 |
| 1260 /** |
1112 * @param {string} path Any path. | 1261 * @param {string} path Any path. |
1113 * @return {string} The root path. | 1262 * @return {string} The root path. |
1114 */ | 1263 */ |
1115 DirectoryModel.getRootPath = function(path) { | 1264 DirectoryModel.getRootPath = function(path) { |
1116 var type = DirectoryModel.getRootType(path); | 1265 var type = DirectoryModel.getRootType(path); |
1117 | 1266 |
1118 if (type == DirectoryModel.RootType.DOWNLOADS) | 1267 if (type == DirectoryModel.RootType.DOWNLOADS) |
1119 return '/' + DirectoryModel.DOWNLOADS_DIRECTORY; | 1268 return '/' + DirectoryModel.DOWNLOADS_DIRECTORY; |
1120 if (type == DirectoryModel.RootType.GDATA) | 1269 if (type == DirectoryModel.RootType.GDATA) |
1121 return '/' + DirectoryModel.GDATA_DIRECTORY; | 1270 return '/' + DirectoryModel.GDATA_DIRECTORY; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1166 * @param {string} path A path. | 1315 * @param {string} path A path. |
1167 * @return {boolean} True if it is a path to the root. | 1316 * @return {boolean} True if it is a path to the root. |
1168 */ | 1317 */ |
1169 DirectoryModel.isRootPath = function(path) { | 1318 DirectoryModel.isRootPath = function(path) { |
1170 if (path[path.length - 1] == '/') | 1319 if (path[path.length - 1] == '/') |
1171 path = path.substring(0, path.length - 1); | 1320 path = path.substring(0, path.length - 1); |
1172 return DirectoryModel.getRootPath(path) == path; | 1321 return DirectoryModel.getRootPath(path) == path; |
1173 }; | 1322 }; |
1174 | 1323 |
1175 /** | 1324 /** |
| 1325 * Checks if the provided path is under gdata search. |
| 1326 * |
| 1327 * @param {string} path Path to be tested. |
| 1328 * @return {boolean} Is the path gdata search path. |
| 1329 */ |
| 1330 DirectoryModel.isGDataSearchPath = function(path) { |
| 1331 return path == DirectoryModel.GDATA_SEARCH_ROOT_PATH || |
| 1332 path.search(DirectoryModel.GDATA_SEARCH_ROOT_PATH + '/') == 0; |
| 1333 }; |
| 1334 |
| 1335 /** |
| 1336 * Creates directory path in which gdata content search results for |query| |
| 1337 * should be displayed. |
| 1338 * |
| 1339 * @param {string} query Search query. |
| 1340 * @return {string} Virtual directory path for search results. |
| 1341 */ |
| 1342 DirectoryModel.createGDataSearchPath = function(query) { |
| 1343 return DirectoryModel.GDATA_SEARCH_ROOT_PATH + '/' + query; |
| 1344 }; |
| 1345 |
| 1346 /** |
1176 * @constructor | 1347 * @constructor |
1177 * @extends cr.EventTarget | 1348 * @extends cr.EventTarget |
1178 * @param {DirectoryEntry} dir Directory to scan. | 1349 * @param {DirectoryEntry} dir Directory to scan. |
1179 * @param {Array.<Entry>|cr.ui.ArrayDataModel} list Target to put the files. | 1350 * @param {Array.<Entry>|cr.ui.ArrayDataModel} list Target to put the files. |
1180 * @param {function} successCallback Callback to call when (and if) scan | 1351 * @param {function} successCallback Callback to call when (and if) scan |
1181 * successfully completed. | 1352 * successfully completed. |
1182 * @param {function} errorCallback Callback to call in case of IO error. | 1353 * @param {function} errorCallback Callback to call in case of IO error. |
1183 * @param {function(Array.<Entry>):void, Function)} preprocessChunk | 1354 * @param {function(Array.<Entry>):void, Function)} preprocessChunk |
1184 * Callback to preprocess each chunk of files. | 1355 * Callback to preprocess each chunk of files. |
1185 * @param {Object.<string, function(Entry):Boolean>} filters The map of filters | 1356 * @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 /** | 1433 /** |
1263 * @private | 1434 * @private |
1264 */ | 1435 */ |
1265 DirectoryModel.Scanner.prototype.recordMetrics_ = function() { | 1436 DirectoryModel.Scanner.prototype.recordMetrics_ = function() { |
1266 metrics.recordInterval('DirectoryScan'); | 1437 metrics.recordInterval('DirectoryScan'); |
1267 if (this.dir_.fullPath == | 1438 if (this.dir_.fullPath == |
1268 '/' + DirectoryModel.DOWNLOADS_DIRECTORY) { | 1439 '/' + DirectoryModel.DOWNLOADS_DIRECTORY) { |
1269 metrics.recordMediumCount('DownloadsCount', this.list_.length); | 1440 metrics.recordMediumCount('DownloadsCount', this.list_.length); |
1270 } | 1441 } |
1271 }; | 1442 }; |
OLD | NEW |