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 19 matching lines...) Expand all Loading... | |
30 | 30 |
31 this.runningScan_ = null; | 31 this.runningScan_ = null; |
32 this.pendingScan_ = null; | 32 this.pendingScan_ = null; |
33 this.rescanTimeout_ = undefined; | 33 this.rescanTimeout_ = undefined; |
34 this.scanFailures_ = 0; | 34 this.scanFailures_ = 0; |
35 | 35 |
36 // DirectoryEntry representing the current directory of the dialog. | 36 // DirectoryEntry representing the current directory of the dialog. |
37 this.currentDirEntry_ = root; | 37 this.currentDirEntry_ = root; |
38 | 38 |
39 this.fileList_.prepareSort = this.prepareSort_.bind(this); | 39 this.fileList_.prepareSort = this.prepareSort_.bind(this); |
40 this.autoSelectIndex_ = 0; | |
41 | 40 |
42 this.rootsList_ = new cr.ui.ArrayDataModel([]); | 41 this.rootsList_ = new cr.ui.ArrayDataModel([]); |
43 this.rootsListSelection_ = new cr.ui.ListSingleSelectionModel(); | 42 this.rootsListSelection_ = new cr.ui.ListSingleSelectionModel(); |
44 | 43 |
45 /** | 44 /** |
46 * A map root.fullPath -> currentDirectory.fullPath. | 45 * A map root.fullPath -> currentDirectory.fullPath. |
47 * @private | 46 * @private |
48 * @type {Object.<string, string>} | 47 * @type {Object.<string, string>} |
49 */ | 48 */ |
50 this.currentDirByRoot_ = {}; | 49 this.currentDirByRoot_ = {}; |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
189 }; | 188 }; |
190 | 189 |
191 /** | 190 /** |
192 * @return {DirectoryEntry} Current directory. | 191 * @return {DirectoryEntry} Current directory. |
193 */ | 192 */ |
194 DirectoryModel.prototype.getCurrentDirEntry = function() { | 193 DirectoryModel.prototype.getCurrentDirEntry = function() { |
195 return this.currentDirEntry_; | 194 return this.currentDirEntry_; |
196 }; | 195 }; |
197 | 196 |
198 /** | 197 /** |
199 * @param {number} value New auto select index. | |
200 */ | |
201 DirectoryModel.prototype.setAutoSelectIndex = function(value) { | |
202 this.autoSelectIndex_ = value; | |
203 }; | |
204 | |
205 /** | |
206 * @private | 198 * @private |
207 * @return {Array.<string>} Names of selected files. | 199 * @return {Array.<string>} Names of selected files. |
208 */ | 200 */ |
209 DirectoryModel.prototype.getSelectedNames_ = function() { | 201 DirectoryModel.prototype.getSelectedNames_ = function() { |
210 var indexes = this.fileListSelection_.selectedIndexes; | 202 var indexes = this.fileListSelection_.selectedIndexes; |
211 var dataModel = this.fileList_; | 203 var dataModel = this.fileList_; |
212 if (dataModel) { | 204 if (dataModel) { |
213 return indexes.map(function(i) { | 205 return indexes.map(function(i) { |
214 return dataModel.item(i).name; | 206 return dataModel.item(i).name; |
215 }); | 207 }); |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
646 onSuccess, errorCallback); | 638 onSuccess, errorCallback); |
647 }; | 639 }; |
648 | 640 |
649 /** | 641 /** |
650 * Changes directory. Causes 'directory-change' event. | 642 * Changes directory. Causes 'directory-change' event. |
651 * | 643 * |
652 * @param {string} path New current directory path. | 644 * @param {string} path New current directory path. |
653 * @param {function} opt_OnError Called if failed. | 645 * @param {function} opt_OnError Called if failed. |
654 */ | 646 */ |
655 DirectoryModel.prototype.changeDirectory = function(path, opt_OnError) { | 647 DirectoryModel.prototype.changeDirectory = function(path, opt_OnError) { |
656 var onDirectoryResolved = function(dirEntry) { | 648 var onDirectoryResolved = this.changeDirectoryEntry_.bind(this, false); |
657 var autoSelect = this.selectIndex.bind(this, this.autoSelectIndex_); | |
658 this.changeDirectoryEntry_(dirEntry, autoSelect, false); | |
659 }.bind(this); | |
660 | 649 |
661 if (this.unmountedGDataEntry_ && | 650 if (this.unmountedGDataEntry_ && |
662 DirectoryModel.getRootType(path) == DirectoryModel.RootType.GDATA) { | 651 DirectoryModel.getRootType(path) == DirectoryModel.RootType.GDATA) { |
663 // TODO(kaznacheeev): Currently if path points to some GData subdirectory | 652 // TODO(kaznacheeev): Currently if path points to some GData subdirectory |
664 // and GData is not mounted we will change to the fake GData root and | 653 // and GData is not mounted we will change to the fake GData root and |
665 // ignore the rest of the path. Consider remembering the path and | 654 // ignore the rest of the path. Consider remembering the path and |
666 // changing to it once GDdata is mounted. This is only relevant for cases | 655 // changing to it once GDdata is mounted. This is only relevant for cases |
667 // when we open the File Manager with an URL pointing to GData (e.g. via | 656 // when we open the File Manager with an URL pointing to GData (e.g. via |
668 // a bookmark). | 657 // a bookmark). |
669 onDirectoryResolved(this.unmountedGDataEntry_); | 658 onDirectoryResolved(this.unmountedGDataEntry_); |
(...skipping 14 matching lines...) Expand all Loading... | |
684 }; | 673 }; |
685 | 674 |
686 /** | 675 /** |
687 * Change the current directory to the directory represented by a | 676 * Change the current directory to the directory represented by a |
688 * DirectoryEntry. | 677 * DirectoryEntry. |
689 * | 678 * |
690 * Dispatches the 'directory-changed' event when the directory is successfully | 679 * Dispatches the 'directory-changed' event when the directory is successfully |
691 * changed. | 680 * changed. |
692 * | 681 * |
693 * @private | 682 * @private |
694 * @param {DirectoryEntry} dirEntry The absolute path to the new directory. | |
695 * @param {function} action Action executed if the directory loads | |
696 * successfully. By default selects the first item (unless it's a save | |
697 * dialog). | |
698 * @param {boolean} initial True if it comes from setupPath and | 683 * @param {boolean} initial True if it comes from setupPath and |
699 * false if caused by an user action. | 684 * false if caused by an user action. |
685 * @param {DirectoryEntry} dirEntry The absolute path to the new directory. | |
dgozman
2012/04/24 11:28:28
It's not a path, but an entry.
Oleg Eterevsky
2012/04/24 11:29:50
Done.
| |
700 */ | 686 */ |
701 DirectoryModel.prototype.changeDirectoryEntry_ = function(dirEntry, action, | 687 DirectoryModel.prototype.changeDirectoryEntry_ = function(initial, dirEntry) { |
702 initial) { | |
703 var previous = this.currentDirEntry_; | 688 var previous = this.currentDirEntry_; |
704 this.currentDirEntry_ = dirEntry; | 689 this.currentDirEntry_ = dirEntry; |
705 function onRescanComplete() { | 690 function onRescanComplete() { |
706 action(); | |
707 // For tests that open the dialog to empty directories, everything | 691 // For tests that open the dialog to empty directories, everything |
708 // is loaded at this point. | 692 // is loaded at this point. |
709 chrome.test.sendMessage('directory-change-complete'); | 693 chrome.test.sendMessage('directory-change-complete'); |
710 } | 694 } |
711 this.updateReadonlyStatus_(); | 695 this.updateReadonlyStatus_(); |
712 this.updateVolumeMetadata_(); | 696 this.updateVolumeMetadata_(); |
713 this.updateRootsListSelection_(); | 697 this.updateRootsListSelection_(); |
714 this.scan_(onRescanComplete); | 698 this.scan_(onRescanComplete); |
715 this.currentDirByRoot_[this.getCurrentRootPath()] = dirEntry.fullPath; | 699 this.currentDirByRoot_[this.getCurrentRootPath()] = dirEntry.fullPath; |
716 | 700 |
(...skipping 25 matching lines...) Expand all Loading... | |
742 var overridden = false; | 726 var overridden = false; |
743 function onExternalDirChange() { overridden = true } | 727 function onExternalDirChange() { overridden = true } |
744 this.addEventListener('directory-changed', onExternalDirChange); | 728 this.addEventListener('directory-changed', onExternalDirChange); |
745 | 729 |
746 var resolveCallback = function(exists) { | 730 var resolveCallback = function(exists) { |
747 this.removeEventListener('directory-changed', onExternalDirChange); | 731 this.removeEventListener('directory-changed', onExternalDirChange); |
748 if (opt_pathResolveCallback) | 732 if (opt_pathResolveCallback) |
749 opt_pathResolveCallback(baseName, leafName, exists && !overridden); | 733 opt_pathResolveCallback(baseName, leafName, exists && !overridden); |
750 }.bind(this); | 734 }.bind(this); |
751 | 735 |
752 var changeDirectoryEntry = function(entry, callback, initial, exists) { | 736 var changeDirectoryEntry = function(entry, initial, exists) { |
753 resolveCallback(exists); | 737 resolveCallback(exists); |
754 if (!overridden) | 738 if (!overridden) |
755 this.changeDirectoryEntry_(entry, callback, initial); | 739 this.changeDirectoryEntry_(initial, entry); |
756 }.bind(this); | 740 }.bind(this); |
757 | 741 |
758 var INITIAL = true; | 742 var INITIAL = true; |
759 var EXISTS = true; | 743 var EXISTS = true; |
760 | 744 |
761 // Split the dirname from the basename. | 745 // Split the dirname from the basename. |
762 var ary = path.match(/^(?:(.*)\/)?([^\/]*)$/); | 746 var ary = path.match(/^(?:(.*)\/)?([^\/]*)$/); |
763 var autoSelect = function() { | |
764 this.selectIndex(this.autoSelectIndex_); | |
765 if (opt_loadedCallback) | |
766 opt_loadedCallback(); | |
767 }.bind(this); | |
768 | 747 |
769 if (!ary) { | 748 if (!ary) { |
770 console.warn('Unable to split default path: ' + path); | 749 console.warn('Unable to split default path: ' + path); |
771 changeDirectoryEntry(this.root_, autoSelect, INITIAL, !EXISTS); | 750 changeDirectoryEntry(this.root_, INITIAL, !EXISTS); |
772 return; | 751 return; |
773 } | 752 } |
774 | 753 |
775 var baseName = ary[1]; | 754 var baseName = ary[1]; |
776 var leafName = ary[2]; | 755 var leafName = ary[2]; |
777 | 756 |
778 function onLeafFound(baseDirEntry, leafEntry) { | 757 function onLeafFound(baseDirEntry, leafEntry) { |
779 if (leafEntry.isDirectory) { | 758 if (leafEntry.isDirectory) { |
780 baseName = path; | 759 baseName = path; |
781 leafName = ''; | 760 leafName = ''; |
782 changeDirectoryEntry(leafEntry, autoSelect, INITIAL, EXISTS); | 761 changeDirectoryEntry(leafEntry, INITIAL, EXISTS); |
783 return; | 762 return; |
784 } | 763 } |
785 | 764 |
786 // Leaf is an existing file, cd to its parent directory and select it. | 765 // Leaf is an existing file, cd to its parent directory and select it. |
787 changeDirectoryEntry(baseDirEntry, | 766 changeDirectoryEntry(baseDirEntry, |
788 function() { | 767 function() { |
789 this.selectEntry(leafEntry.name); | 768 this.selectEntry(leafEntry.name); |
790 if (opt_loadedCallback) | 769 if (opt_loadedCallback) |
791 opt_loadedCallback(); | 770 opt_loadedCallback(); |
792 }.bind(this), | 771 }.bind(this), |
793 !INITIAL /*HACK*/, | 772 !INITIAL /*HACK*/, |
794 EXISTS); | 773 EXISTS); |
795 // TODO(kaznacheev): Fix history.replaceState for the File Browser and | 774 // TODO(kaznacheev): Fix history.replaceState for the File Browser and |
796 // change !INITIAL to INITIAL. Passing |false| makes things | 775 // change !INITIAL to INITIAL. Passing |false| makes things |
797 // less ugly for now. | 776 // less ugly for now. |
798 } | 777 } |
799 | 778 |
800 function onLeafError(baseDirEntry, err) { | 779 function onLeafError(baseDirEntry, err) { |
801 // Usually, leaf does not exist, because it's just a suggested file name. | 780 // Usually, leaf does not exist, because it's just a suggested file name. |
802 if (err.code != FileError.NOT_FOUND_ERR) | 781 if (err.code != FileError.NOT_FOUND_ERR) |
803 console.log('Unexpected error resolving default leaf: ' + err); | 782 console.log('Unexpected error resolving default leaf: ' + err); |
804 changeDirectoryEntry(baseDirEntry, autoSelect, INITIAL, !EXISTS); | 783 changeDirectoryEntry(baseDirEntry, INITIAL, !EXISTS); |
805 } | 784 } |
806 | 785 |
807 var onBaseError = function(err) { | 786 var onBaseError = function(err) { |
808 console.log('Unexpected error resolving default base "' + | 787 console.log('Unexpected error resolving default base "' + |
809 baseName + '": ' + err); | 788 baseName + '": ' + err); |
810 if (path != '/' + DirectoryModel.DOWNLOADS_DIRECTORY) { | 789 if (path != '/' + DirectoryModel.DOWNLOADS_DIRECTORY) { |
811 // Can't find the provided path, let's go to default one instead. | 790 // Can't find the provided path, let's go to default one instead. |
812 resolveCallback(!EXISTS); | 791 resolveCallback(!EXISTS); |
813 if (!overridden) | 792 if (!overridden) |
814 this.setupDefaultPath(opt_loadedCallback); | 793 this.setupDefaultPath(opt_loadedCallback); |
815 } else { | 794 } else { |
816 // Well, we can't find the downloads dir. Let's just show something, | 795 // Well, we can't find the downloads dir. Let's just show something, |
817 // or we will get an infinite recursion. | 796 // or we will get an infinite recursion. |
818 changeDirectoryEntry(this.root_, opt_loadedCallback, INITIAL, !EXISTS); | 797 changeDirectoryEntry(this.root_, opt_loadedCallback, INITIAL, !EXISTS); |
819 } | 798 } |
820 }.bind(this); | 799 }.bind(this); |
821 | 800 |
822 var onBaseFound = function(baseDirEntry) { | 801 var onBaseFound = function(baseDirEntry) { |
823 if (!leafName) { | 802 if (!leafName) { |
824 // Default path is just a directory, cd to it and we're done. | 803 // Default path is just a directory, cd to it and we're done. |
825 changeDirectoryEntry(baseDirEntry, autoSelect, INITIAL, !EXISTS); | 804 changeDirectoryEntry(baseDirEntry, INITIAL, !EXISTS); |
826 return; | 805 return; |
827 } | 806 } |
828 | 807 |
829 util.resolvePath(this.root_, path, | 808 util.resolvePath(this.root_, path, |
830 onLeafFound.bind(this, baseDirEntry), | 809 onLeafFound.bind(this, baseDirEntry), |
831 onLeafError.bind(this, baseDirEntry)); | 810 onLeafError.bind(this, baseDirEntry)); |
832 }.bind(this); | 811 }.bind(this); |
833 | 812 |
834 var root = this.root_; | 813 var root = this.root_; |
835 if (baseName) { | 814 if (baseName) { |
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1298 /** | 1277 /** |
1299 * @private | 1278 * @private |
1300 */ | 1279 */ |
1301 DirectoryModel.Scanner.prototype.recordMetrics_ = function() { | 1280 DirectoryModel.Scanner.prototype.recordMetrics_ = function() { |
1302 metrics.recordInterval('DirectoryScan'); | 1281 metrics.recordInterval('DirectoryScan'); |
1303 if (this.dir_.fullPath == | 1282 if (this.dir_.fullPath == |
1304 '/' + DirectoryModel.DOWNLOADS_DIRECTORY) { | 1283 '/' + DirectoryModel.DOWNLOADS_DIRECTORY) { |
1305 metrics.recordMediumCount('DownloadsCount', this.list_.length); | 1284 metrics.recordMediumCount('DownloadsCount', this.list_.length); |
1306 } | 1285 } |
1307 }; | 1286 }; |
OLD | NEW |