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

Side by Side Diff: chrome/browser/resources/file_manager/js/directory_model.js

Issue 10204015: Do not auto-select the first file on entering a folder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome/browser/resources/file_manager/js/file_manager.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // If directory files changes too often, don't rescan directory more than once 5 // If directory files changes too often, don't rescan directory more than once
6 // per specified interval 6 // per specified interval
7 var SIMULTANEOUS_RESCAN_INTERVAL = 1000; 7 var SIMULTANEOUS_RESCAN_INTERVAL = 1000;
8 // Used for operations that require almost instant rescan. 8 // Used for operations that require almost instant rescan.
9 var SHORT_RESCAN_INTERVAL = 100; 9 var SHORT_RESCAN_INTERVAL = 100;
10 10
(...skipping 19 matching lines...) Expand all
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
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
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
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
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
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 };
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/resources/file_manager/js/file_manager.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698