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

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

Issue 10222005: Reapply https://chromiumcodereview.appspot.com/10204015. Fix (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 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 }; 195 };
197 196
198 /** 197 /**
199 * @return {DirectoryEntry} Current directory. 198 * @return {DirectoryEntry} Current directory.
200 */ 199 */
201 DirectoryModel.prototype.getCurrentDirEntry = function() { 200 DirectoryModel.prototype.getCurrentDirEntry = function() {
202 return this.currentDirEntry_; 201 return this.currentDirEntry_;
203 }; 202 };
204 203
205 /** 204 /**
206 * @param {number} value New auto select index.
207 */
208 DirectoryModel.prototype.setAutoSelectIndex = function(value) {
209 this.autoSelectIndex_ = value;
210 };
211
212 /**
213 * @private 205 * @private
214 * @return {Array.<string>} Names of selected files. 206 * @return {Array.<string>} Names of selected files.
215 */ 207 */
216 DirectoryModel.prototype.getSelectedNames_ = function() { 208 DirectoryModel.prototype.getSelectedNames_ = function() {
217 var indexes = this.fileListSelection_.selectedIndexes; 209 var indexes = this.fileListSelection_.selectedIndexes;
218 var dataModel = this.fileList_; 210 var dataModel = this.fileList_;
219 if (dataModel) { 211 if (dataModel) {
220 return indexes.map(function(i) { 212 return indexes.map(function(i) {
221 return dataModel.item(i).name; 213 return dataModel.item(i).name;
222 }); 214 });
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 onSuccess, errorCallback); 645 onSuccess, errorCallback);
654 }; 646 };
655 647
656 /** 648 /**
657 * Changes directory. Causes 'directory-change' event. 649 * Changes directory. Causes 'directory-change' event.
658 * 650 *
659 * @param {string} path New current directory path. 651 * @param {string} path New current directory path.
660 * @param {function} opt_OnError Called if failed. 652 * @param {function} opt_OnError Called if failed.
661 */ 653 */
662 DirectoryModel.prototype.changeDirectory = function(path, opt_OnError) { 654 DirectoryModel.prototype.changeDirectory = function(path, opt_OnError) {
663 var onDirectoryResolved = function(dirEntry) { 655 var onDirectoryResolved = this.changeDirectoryEntry_.bind(this, false);
664 var autoSelect = this.selectIndex.bind(this, this.autoSelectIndex_);
665 this.changeDirectoryEntry_(dirEntry, autoSelect, false);
666 }.bind(this);
667 656
668 if (this.unmountedGDataEntry_ && 657 if (this.unmountedGDataEntry_ &&
669 DirectoryModel.getRootType(path) == DirectoryModel.RootType.GDATA) { 658 DirectoryModel.getRootType(path) == DirectoryModel.RootType.GDATA) {
670 // TODO(kaznacheeev): Currently if path points to some GData subdirectory 659 // TODO(kaznacheeev): Currently if path points to some GData subdirectory
671 // and GData is not mounted we will change to the fake GData root and 660 // and GData is not mounted we will change to the fake GData root and
672 // ignore the rest of the path. Consider remembering the path and 661 // ignore the rest of the path. Consider remembering the path and
673 // changing to it once GDdata is mounted. This is only relevant for cases 662 // changing to it once GDdata is mounted. This is only relevant for cases
674 // when we open the File Manager with an URL pointing to GData (e.g. via 663 // when we open the File Manager with an URL pointing to GData (e.g. via
675 // a bookmark). 664 // a bookmark).
676 onDirectoryResolved(this.unmountedGDataEntry_); 665 onDirectoryResolved(this.unmountedGDataEntry_);
(...skipping 14 matching lines...) Expand all
691 }; 680 };
692 681
693 /** 682 /**
694 * Change the current directory to the directory represented by a 683 * Change the current directory to the directory represented by a
695 * DirectoryEntry. 684 * DirectoryEntry.
696 * 685 *
697 * Dispatches the 'directory-changed' event when the directory is successfully 686 * Dispatches the 'directory-changed' event when the directory is successfully
698 * changed. 687 * changed.
699 * 688 *
700 * @private 689 * @private
701 * @param {DirectoryEntry} dirEntry The absolute path to the new directory.
702 * @param {function} action Action executed if the directory loads
703 * successfully. By default selects the first item (unless it's a save
704 * dialog).
705 * @param {boolean} initial True if it comes from setupPath and 690 * @param {boolean} initial True if it comes from setupPath and
706 * false if caused by an user action. 691 * false if caused by an user action.
692 * @param {DirectoryEntry} dirEntry The absolute path to the new directory.
693 * @param {function} opt_callback Executed if the directory loads successfully.
707 */ 694 */
708 DirectoryModel.prototype.changeDirectoryEntry_ = function(dirEntry, action, 695 DirectoryModel.prototype.changeDirectoryEntry_ = function(initial, dirEntry,
709 initial) { 696 opt_callback) {
710 var previous = this.currentDirEntry_; 697 var previous = this.currentDirEntry_;
711 this.currentDirEntry_ = dirEntry; 698 this.currentDirEntry_ = dirEntry;
712 function onRescanComplete() { 699 function onRescanComplete() {
713 action(); 700 if (opt_callback)
701 opt_callback();
714 // For tests that open the dialog to empty directories, everything 702 // For tests that open the dialog to empty directories, everything
715 // is loaded at this point. 703 // is loaded at this point.
716 chrome.test.sendMessage('directory-change-complete'); 704 chrome.test.sendMessage('directory-change-complete');
717 } 705 }
718 this.updateRootsListSelection_(); 706 this.updateRootsListSelection_();
719 this.scan_(onRescanComplete); 707 this.scan_(onRescanComplete);
720 this.currentDirByRoot_[this.getCurrentRootPath()] = dirEntry.fullPath; 708 this.currentDirByRoot_[this.getCurrentRootPath()] = dirEntry.fullPath;
721 709
722 var e = new cr.Event('directory-changed'); 710 var e = new cr.Event('directory-changed');
723 e.previousDirEntry = previous; 711 e.previousDirEntry = previous;
(...skipping 23 matching lines...) Expand all
747 var overridden = false; 735 var overridden = false;
748 function onExternalDirChange() { overridden = true } 736 function onExternalDirChange() { overridden = true }
749 this.addEventListener('directory-changed', onExternalDirChange); 737 this.addEventListener('directory-changed', onExternalDirChange);
750 738
751 var resolveCallback = function(exists) { 739 var resolveCallback = function(exists) {
752 this.removeEventListener('directory-changed', onExternalDirChange); 740 this.removeEventListener('directory-changed', onExternalDirChange);
753 if (opt_pathResolveCallback) 741 if (opt_pathResolveCallback)
754 opt_pathResolveCallback(baseName, leafName, exists && !overridden); 742 opt_pathResolveCallback(baseName, leafName, exists && !overridden);
755 }.bind(this); 743 }.bind(this);
756 744
757 var changeDirectoryEntry = function(entry, callback, initial, exists) { 745 var changeDirectoryEntry = function(entry, initial, exists, opt_callback) {
758 resolveCallback(exists); 746 resolveCallback(exists);
759 if (!overridden) 747 if (!overridden)
760 this.changeDirectoryEntry_(entry, callback, initial); 748 this.changeDirectoryEntry_(initial, entry, opt_callback);
761 }.bind(this); 749 }.bind(this);
762 750
763 var INITIAL = true; 751 var INITIAL = true;
764 var EXISTS = true; 752 var EXISTS = true;
765 753
766 // Split the dirname from the basename. 754 // Split the dirname from the basename.
767 var ary = path.match(/^(?:(.*)\/)?([^\/]*)$/); 755 var ary = path.match(/^(?:(.*)\/)?([^\/]*)$/);
768 var autoSelect = function() {
769 this.selectIndex(this.autoSelectIndex_);
770 if (opt_loadedCallback)
771 opt_loadedCallback();
772 }.bind(this);
773 756
774 if (!ary) { 757 if (!ary) {
775 console.warn('Unable to split default path: ' + path); 758 console.warn('Unable to split default path: ' + path);
776 changeDirectoryEntry(this.root_, autoSelect, INITIAL, !EXISTS); 759 changeDirectoryEntry(this.root_, INITIAL, !EXISTS);
777 return; 760 return;
778 } 761 }
779 762
780 var baseName = ary[1]; 763 var baseName = ary[1];
781 var leafName = ary[2]; 764 var leafName = ary[2];
782 765
783 function onLeafFound(baseDirEntry, leafEntry) { 766 function onLeafFound(baseDirEntry, leafEntry) {
784 if (leafEntry.isDirectory) { 767 if (leafEntry.isDirectory) {
785 baseName = path; 768 baseName = path;
786 leafName = ''; 769 leafName = '';
787 changeDirectoryEntry(leafEntry, autoSelect, INITIAL, EXISTS); 770 changeDirectoryEntry(leafEntry, INITIAL, EXISTS);
788 return; 771 return;
789 } 772 }
790 773
791 // Leaf is an existing file, cd to its parent directory and select it. 774 // Leaf is an existing file, cd to its parent directory and select it.
792 changeDirectoryEntry(baseDirEntry, 775 changeDirectoryEntry(baseDirEntry,
776 !INITIAL /*HACK*/,
777 EXISTS,
793 function() { 778 function() {
794 this.selectEntry(leafEntry.name); 779 this.selectEntry(leafEntry.name);
795 if (opt_loadedCallback) 780 if (opt_loadedCallback)
796 opt_loadedCallback(); 781 opt_loadedCallback();
797 }.bind(this), 782 }.bind(this));
798 !INITIAL /*HACK*/,
799 EXISTS);
800 // TODO(kaznacheev): Fix history.replaceState for the File Browser and 783 // TODO(kaznacheev): Fix history.replaceState for the File Browser and
801 // change !INITIAL to INITIAL. Passing |false| makes things 784 // change !INITIAL to INITIAL. Passing |false| makes things
802 // less ugly for now. 785 // less ugly for now.
803 } 786 }
804 787
805 function onLeafError(baseDirEntry, err) { 788 function onLeafError(baseDirEntry, err) {
806 // Usually, leaf does not exist, because it's just a suggested file name. 789 // Usually, leaf does not exist, because it's just a suggested file name.
807 if (err.code != FileError.NOT_FOUND_ERR) 790 if (err.code != FileError.NOT_FOUND_ERR)
808 console.log('Unexpected error resolving default leaf: ' + err); 791 console.log('Unexpected error resolving default leaf: ' + err);
809 changeDirectoryEntry(baseDirEntry, autoSelect, INITIAL, !EXISTS); 792 changeDirectoryEntry(baseDirEntry, INITIAL, !EXISTS);
810 } 793 }
811 794
812 var onBaseError = function(err) { 795 var onBaseError = function(err) {
813 console.log('Unexpected error resolving default base "' + 796 console.log('Unexpected error resolving default base "' +
814 baseName + '": ' + err); 797 baseName + '": ' + err);
815 if (path != this.getDefaultDirectory()) { 798 if (path != this.getDefaultDirectory()) {
816 // Can't find the provided path, let's go to default one instead. 799 // Can't find the provided path, let's go to default one instead.
817 resolveCallback(!EXISTS); 800 resolveCallback(!EXISTS);
818 if (!overridden) 801 if (!overridden)
819 this.setupDefaultPath(opt_loadedCallback); 802 this.setupDefaultPath(opt_loadedCallback);
820 } else { 803 } else {
821 // Well, we can't find the downloads dir. Let's just show something, 804 // Well, we can't find the downloads dir. Let's just show something,
822 // or we will get an infinite recursion. 805 // or we will get an infinite recursion.
823 changeDirectoryEntry(this.root_, opt_loadedCallback, INITIAL, !EXISTS); 806 changeDirectoryEntry(this.root_, opt_loadedCallback, INITIAL, !EXISTS);
824 } 807 }
825 }.bind(this); 808 }.bind(this);
826 809
827 var onBaseFound = function(baseDirEntry) { 810 var onBaseFound = function(baseDirEntry) {
828 if (!leafName) { 811 if (!leafName) {
829 // Default path is just a directory, cd to it and we're done. 812 // Default path is just a directory, cd to it and we're done.
830 changeDirectoryEntry(baseDirEntry, autoSelect, INITIAL, !EXISTS); 813 changeDirectoryEntry(baseDirEntry, INITIAL, !EXISTS);
831 return; 814 return;
832 } 815 }
833 816
834 util.resolvePath(this.root_, path, 817 util.resolvePath(this.root_, path,
835 onLeafFound.bind(this, baseDirEntry), 818 onLeafFound.bind(this, baseDirEntry),
836 onLeafError.bind(this, baseDirEntry)); 819 onLeafError.bind(this, baseDirEntry));
837 }.bind(this); 820 }.bind(this);
838 821
839 var root = this.root_; 822 var root = this.root_;
840 if (!baseName) 823 if (!baseName)
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
1244 /** 1227 /**
1245 * @private 1228 * @private
1246 */ 1229 */
1247 DirectoryModel.Scanner.prototype.recordMetrics_ = function() { 1230 DirectoryModel.Scanner.prototype.recordMetrics_ = function() {
1248 metrics.recordInterval('DirectoryScan'); 1231 metrics.recordInterval('DirectoryScan');
1249 if (this.dir_.fullPath == 1232 if (this.dir_.fullPath ==
1250 '/' + DirectoryModel.DOWNLOADS_DIRECTORY) { 1233 '/' + DirectoryModel.DOWNLOADS_DIRECTORY) {
1251 metrics.recordMediumCount('DownloadsCount', this.list_.length); 1234 metrics.recordMediumCount('DownloadsCount', this.list_.length);
1252 } 1235 }
1253 }; 1236 };
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