| 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 |