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

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

Issue 10146008: Remember current directory for each volume. (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 21 matching lines...) Expand all
32 this.scanFailures_ = 0; 32 this.scanFailures_ = 0;
33 33
34 // DirectoryEntry representing the current directory of the dialog. 34 // DirectoryEntry representing the current directory of the dialog.
35 this.currentDirEntry_ = root; 35 this.currentDirEntry_ = root;
36 36
37 this.fileList_.prepareSort = this.prepareSort_.bind(this); 37 this.fileList_.prepareSort = this.prepareSort_.bind(this);
38 this.autoSelectIndex_ = 0; 38 this.autoSelectIndex_ = 0;
39 39
40 this.rootsList_ = new cr.ui.ArrayDataModel([]); 40 this.rootsList_ = new cr.ui.ArrayDataModel([]);
41 this.rootsListSelection_ = new cr.ui.ListSingleSelectionModel(); 41 this.rootsListSelection_ = new cr.ui.ListSingleSelectionModel();
42 this.rootsListSelection_.addEventListener( 42 this.currentRootDirEntry_ = root;
43 'change', this.onRootsSelectionChanged_.bind(this)); 43 /**
44 * A map root.fullPath -> currentDirectory.fullPath.
45 * @private
46 * @type {Object.<string, string>}
47 */
48 this.currentDirByRoot_ = {};
44 49
45 // The map 'name' -> callback. Callbacks are function(entry) -> boolean. 50 // The map 'name' -> callback. Callbacks are function(entry) -> boolean.
46 this.filters_ = {}; 51 this.filters_ = {};
47 this.filterHidden = true; 52 this.filterHidden = true;
48 53
49 // Readonly status. 54 // Readonly status.
50 this.readonly_ = false; 55 this.readonly_ = false;
51 this.currentVolumeMetadata_ = {rootPath: '/'}; 56 this.currentVolumeMetadata_ = {rootPath: '/'};
52 this.offline_ = false; 57 this.offline_ = false;
53 } 58 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 103
99 /** 104 /**
100 * Selection in the fileList. 105 * Selection in the fileList.
101 * @type {cr.ui.ListSelectionModel|cr.ui.ListSingleSelectionModel} 106 * @type {cr.ui.ListSelectionModel|cr.ui.ListSingleSelectionModel}
102 */ 107 */
103 get fileListSelection() { 108 get fileListSelection() {
104 return this.fileListSelection_; 109 return this.fileListSelection_;
105 }, 110 },
106 111
107 /** 112 /**
108 * Top level Directories from user perspective.
109 * @type {cr.ui.ArrayDataModel}
110 */
111 get rootsList() {
112 return this.rootsList_;
113 },
114
115 /**
116 * Selection in the rootsList. 113 * Selection in the rootsList.
117 * @type {cr.ui.ListSingleSelectionModel} 114 * @type {cr.ui.ListSingleSelectionModel}
118 */ 115 */
119 get rootsListSelection() { 116 get rootsListSelection() {
120 return this.rootsListSelection_; 117 return this.rootsListSelection_;
121 }, 118 },
122 119
123 /**
124 * Root path for the current directory (parent directory is not navigatable
125 * for the user).
126 * @type {string}
127 */
128 get rootPath() {
129 return DirectoryModel.getRootPath(this.currentEntry.fullPath);
130 },
131
132 get rootType() { 120 get rootType() {
133 return DirectoryModel.getRootType(this.currentEntry.fullPath); 121 return DirectoryModel.getRootType(this.currentEntry.fullPath);
134 }, 122 },
135 123
136 get rootName() { 124 get rootName() {
137 return DirectoryModel.getRootName(this.currentEntry.fullPath); 125 return DirectoryModel.getRootName(this.currentEntry.fullPath);
138 }, 126 },
139 127
140 get rootEntry() { 128 get rootEntry() {
141 return this.rootsList.item(this.rootsListSelection.selectedIndex); 129 return this.rootsList_.item(this.rootsListSelection.selectedIndex);
142 }, 130 },
143 131
144 /** 132 /**
145 * True if current directory is read only. 133 * True if current directory is read only.
146 * @type {boolean} 134 * @type {boolean}
147 */ 135 */
148 get readonly() { 136 get readonly() {
149 return this.readonly_; 137 return this.readonly_;
150 }, 138 },
151 139
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 }, 227 },
240 228
241 set leadName(value) { 229 set leadName(value) {
242 for (var i = 0; i < this.fileList_.length; i++) { 230 for (var i = 0; i < this.fileList_.length; i++) {
243 if (this.fileList_.item(i).name == value) { 231 if (this.fileList_.item(i).name == value) {
244 this.fileListSelection_.leadIndex = i; 232 this.fileListSelection_.leadIndex = i;
245 return; 233 return;
246 } 234 }
247 } 235 }
248 } 236 }
249 }; 237 };
Vladislav Kaznacheev 2012/04/20 14:55:11 nit: if you renamed these functions in place it wo
Oleg Eterevsky 2012/04/20 15:00:32 Unfortunately, they were defined as fields in Dir
250 238
251 /** 239 /**
240 * @return {cr.ui.ArrayDataModel} The list of roots.
241 */
242 DirectoryModel.prototype.getRootsList = function() {
243 return this.rootsList_;
244 };
245
246 /**
247 * @return {string} Root path for the current directory (parent directory is
248 * not navigatable for the user).
249 */
250 DirectoryModel.prototype.getCurrentRootPath = function() {
251 return DirectoryModel.getRootPath(this.currentDirEntry_.fullPath);
252 };
253
254 /**
252 * Add a filter for directory contents. 255 * Add a filter for directory contents.
253 * @param {string} name An identifier of the filter (used when removing it). 256 * @param {string} name An identifier of the filter (used when removing it).
254 * @param {function(Entry):boolean} filter Hide file if false. 257 * @param {function(Entry):boolean} filter Hide file if false.
255 */ 258 */
256 DirectoryModel.prototype.addFilter = function(name, filter) { 259 DirectoryModel.prototype.addFilter = function(name, filter) {
257 this.filters_[name] = filter; 260 this.filters_[name] = filter;
258 this.rescanSoon(); 261 this.rescanSoon();
259 }; 262 };
260 263
261 /** 264 /**
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 return; 325 return;
323 } 326 }
324 327
325 this.runningScan_ = this.createScanner_(fileList, successCallback); 328 this.runningScan_ = this.createScanner_(fileList, successCallback);
326 this.runningScan_.run(); 329 this.runningScan_.run();
327 }; 330 };
328 331
329 /** 332 /**
330 * @private 333 * @private
331 * @param {Array.<Entry>|cr.ui.ArrayDataModel} list 334 * @param {Array.<Entry>|cr.ui.ArrayDataModel} list
332 * @param {function} successCallback 335 * @param {function} successCallback Callback on success.
333 * @return {DirectoryModel.Scanner} 336 * @return {DirectoryModel.Scanner} New Scanner instance.
334 */ 337 */
335 DirectoryModel.prototype.createScanner_ = function(list, successCallback) { 338 DirectoryModel.prototype.createScanner_ = function(list, successCallback) {
336 var self = this; 339 var self = this;
337 function onSuccess() { 340 function onSuccess() {
338 self.scanFailures_ = 0; 341 self.scanFailures_ = 0;
339 successCallback(); 342 successCallback();
340 if (self.pendingScan_) { 343 if (self.pendingScan_) {
341 self.runningScan_ = self.pendingScan_; 344 self.runningScan_ = self.pendingScan_;
342 self.pendingScan_ = null; 345 self.pendingScan_ = null;
343 self.runningScan_.run(); 346 self.runningScan_.run();
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 function onRescanComplete() { 662 function onRescanComplete() {
660 action(); 663 action();
661 // For tests that open the dialog to empty directories, everything 664 // For tests that open the dialog to empty directories, everything
662 // is loaded at this point. 665 // is loaded at this point.
663 chrome.test.sendMessage('directory-change-complete'); 666 chrome.test.sendMessage('directory-change-complete');
664 } 667 }
665 this.updateReadonlyStatus_(); 668 this.updateReadonlyStatus_();
666 this.updateVolumeMetadata_(); 669 this.updateVolumeMetadata_();
667 this.updateRootsListSelection_(); 670 this.updateRootsListSelection_();
668 this.scan_(onRescanComplete); 671 this.scan_(onRescanComplete);
672 this.currentDirByRoot_[this.getCurrentRootPath()] = dirEntry.fullPath;
669 673
670 var e = new cr.Event('directory-changed'); 674 var e = new cr.Event('directory-changed');
671 e.previousDirEntry = previous; 675 e.previousDirEntry = previous;
672 e.newDirEntry = dirEntry; 676 e.newDirEntry = dirEntry;
673 e.initial = initial; 677 e.initial = initial;
674 this.dispatchEvent(e); 678 this.dispatchEvent(e);
675 }; 679 };
676 680
677 /** 681 /**
678 * Change the state of the model to reflect the specified path (either a 682 * Change the state of the model to reflect the specified path (either a
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
994 } 998 }
995 }; 999 };
996 1000
997 /** 1001 /**
998 * @param {function} opt_callback Called when all roots are resolved. 1002 * @param {function} opt_callback Called when all roots are resolved.
999 * @param {boolean} opt_resolveGData If true GData should be resolved for real, 1003 * @param {boolean} opt_resolveGData If true GData should be resolved for real,
1000 * If false a stub entry should be created. 1004 * If false a stub entry should be created.
1001 */ 1005 */
1002 DirectoryModel.prototype.updateRoots = function(opt_callback, 1006 DirectoryModel.prototype.updateRoots = function(opt_callback,
1003 opt_resolveGData) { 1007 opt_resolveGData) {
1004 console.log('resolving roots');
1005 var self = this; 1008 var self = this;
1006 this.resolveRoots_(function(rootEntries) { 1009 this.resolveRoots_(function(rootEntries) {
1007 console.log('resolved roots:', rootEntries);
1008 var dm = self.rootsList_; 1010 var dm = self.rootsList_;
1009 var args = [0, dm.length].concat(rootEntries); 1011 var args = [0, dm.length].concat(rootEntries);
1010 dm.splice.apply(dm, args); 1012 dm.splice.apply(dm, args);
1011 1013
1012 self.updateRootsListSelection_(); 1014 self.updateRootsListSelection_();
1013 1015
1014 if (opt_callback) 1016 if (opt_callback)
1015 opt_callback(); 1017 opt_callback();
1016 }, opt_resolveGData); 1018 }, opt_resolveGData);
1017 }; 1019 };
1018 1020
1019 /** 1021 /**
1022 * Register a listener for a new root element in left menu.
1020 * @private 1023 * @private
1021 * @param {Event} event 1024 * @param {HTMLElement} li List item representing a volume.
1025 * @param {Entry} entry Root directory entry.
1022 */ 1026 */
1023 DirectoryModel.prototype.onRootsSelectionChanged_ = function(event) { 1027 DirectoryModel.prototype.registerRootClickListener_ = function append(li,
1024 var root = this.rootsList.item(this.rootsListSelection.selectedIndex); 1028 entry) {
1025 if (root && this.rootPath != root.fullPath) 1029 li.addEventListener('click', this.onRootClick_.bind(this, entry));
1026 this.changeDirectory(root.fullPath); 1030 };
1031
1032 /**
1033 * Handler for root item being clicked.
1034 * @private
1035 * @param {Entry} entry Entry to navigate to.
1036 * @param {Event} event The event.
1037 */
1038 DirectoryModel.prototype.onRootClick_ = function(entry, event) {
1039 var new_path = entry.fullPath;
1040 if (entry.fullPath == this.getCurrentRootPath()) {
1041 this.changeDirectory(entry.fullPath);
1042 } else {
1043 this.changeDirectory(this.currentDirByRoot_[entry.fullPath] ||
1044 entry.fullPath);
1045 }
1027 }; 1046 };
1028 1047
1029 /** 1048 /**
1030 * @private 1049 * @private
1031 */ 1050 */
1032 DirectoryModel.prototype.updateRootsListSelection_ = function() { 1051 DirectoryModel.prototype.updateRootsListSelection_ = function() {
1033 var roots = this.rootsList_; 1052 var roots = this.rootsList_;
1034 var rootPath = this.rootPath; 1053 var rootPath = this.getCurrentRootPath();
1035 for (var index = 0; index < roots.length; index++) { 1054 for (var index = 0; index < roots.length; index++) {
1036 if (roots.item(index).fullPath == rootPath) { 1055 if (roots.item(index).fullPath == rootPath) {
1037 this.rootsListSelection.selectedIndex = index; 1056 this.rootsListSelection.selectedIndex = index;
1038 return; 1057 return;
1039 } 1058 }
1040 } 1059 }
1041 this.rootsListSelection.selectedIndex = -1; 1060 this.rootsListSelection.selectedIndex = -1;
1042 }; 1061 };
1043 1062
1044 /** 1063 /**
(...skipping 16 matching lines...) Expand all
1061 default: 1080 default:
1062 this.readonly_ = true; 1081 this.readonly_ = true;
1063 break; 1082 break;
1064 } 1083 }
1065 }; 1084 };
1066 1085
1067 /** 1086 /**
1068 * @private 1087 * @private
1069 */ 1088 */
1070 DirectoryModel.prototype.updateVolumeMetadata_ = function() { 1089 DirectoryModel.prototype.updateVolumeMetadata_ = function() {
1071 var rootPath = this.rootPath; 1090 var rootPath = this.getCurrentRootPath();
1072 if (this.currentVolumeMetadata_.rootPath != rootPath) { 1091 if (this.currentVolumeMetadata_.rootPath != rootPath) {
1073 var metadata = this.currentVolumeMetadata_ = {rootPath: rootPath}; 1092 var metadata = this.currentVolumeMetadata_ = {rootPath: rootPath};
1074 if (DirectoryModel.getRootType(rootPath) == 1093 if (DirectoryModel.getRootType(rootPath) ==
1075 DirectoryModel.RootType.REMOVABLE) { 1094 DirectoryModel.RootType.REMOVABLE) {
1076 var self = this; 1095 var self = this;
1077 this.root_.getDirectory(rootPath, {}, function(entry) { 1096 this.root_.getDirectory(rootPath, {}, function(entry) {
1078 chrome.fileBrowserPrivate.getVolumeMetadata(entry.toURL(), 1097 chrome.fileBrowserPrivate.getVolumeMetadata(entry.toURL(),
1079 function(systemMetadata) { 1098 function(systemMetadata) {
1080 if (systemMetadata) { 1099 if (systemMetadata) {
1081 metadata.isReadOnly = systemMetadata.isReadOnly; 1100 metadata.isReadOnly = systemMetadata.isReadOnly;
1082 self.updateReadonlyStatus_(); 1101 self.updateReadonlyStatus_();
1083 } 1102 }
1084 }); 1103 });
1085 }); 1104 });
1086 } 1105 }
1087 } 1106 }
1088 }; 1107 };
1089 1108
1090 /** 1109 /**
1091 * @param {string} path 1110 * @param {string} path Any path in the file system.
1092 * @return {string} The root path. 1111 * @return {string} The root path.
1093 */ 1112 */
1094 DirectoryModel.getRootPath = function(path) { 1113 DirectoryModel.getRootPath = function(path) {
1095 var type = DirectoryModel.getRootType(path); 1114 var type = DirectoryModel.getRootType(path);
1096 1115
1097 if (type == DirectoryModel.RootType.DOWNLOADS) 1116 if (type == DirectoryModel.RootType.DOWNLOADS)
1098 return '/' + DirectoryModel.DOWNLOADS_DIRECTORY; 1117 return '/' + DirectoryModel.DOWNLOADS_DIRECTORY;
1099 if (type == DirectoryModel.RootType.GDATA) 1118 if (type == DirectoryModel.RootType.GDATA)
1100 return '/' + DirectoryModel.GDATA_DIRECTORY; 1119 return '/' + DirectoryModel.GDATA_DIRECTORY;
1101 1120
(...skipping 13 matching lines...) Expand all
1115 * @param {string} path 1134 * @param {string} path
1116 * @return {string} 1135 * @return {string}
1117 */ 1136 */
1118 DirectoryModel.getRootName = function(path) { 1137 DirectoryModel.getRootName = function(path) {
1119 var root = DirectoryModel.getRootPath(path); 1138 var root = DirectoryModel.getRootPath(path);
1120 var index = root.lastIndexOf('/'); 1139 var index = root.lastIndexOf('/');
1121 return index == -1 ? root : root.substring(index + 1); 1140 return index == -1 ? root : root.substring(index + 1);
1122 }; 1141 };
1123 1142
1124 /** 1143 /**
1125 * @param {string} path 1144 * @param {string} path Path.
1126 * @return {string} 1145 * @return {string} A root type.
1127 */ 1146 */
1128 DirectoryModel.getRootType = function(path) { 1147 DirectoryModel.getRootType = function(path) {
1129 function isTop(dir) { 1148 function isTop(dir) {
1130 return path.substr(1, dir.length) == dir; 1149 return path.substr(1, dir.length) == dir;
1131 } 1150 }
1132 1151
1133 if (isTop(DirectoryModel.DOWNLOADS_DIRECTORY)) 1152 if (isTop(DirectoryModel.DOWNLOADS_DIRECTORY))
1134 return DirectoryModel.RootType.DOWNLOADS; 1153 return DirectoryModel.RootType.DOWNLOADS;
1135 else if (isTop(DirectoryModel.GDATA_DIRECTORY)) 1154 if (isTop(DirectoryModel.GDATA_DIRECTORY))
1136 return DirectoryModel.RootType.GDATA; 1155 return DirectoryModel.RootType.GDATA;
1137 else if (isTop(DirectoryModel.ARCHIVE_DIRECTORY)) 1156 if (isTop(DirectoryModel.ARCHIVE_DIRECTORY))
1138 return DirectoryModel.RootType.ARCHIVE; 1157 return DirectoryModel.RootType.ARCHIVE;
1139 else if (isTop(DirectoryModel.REMOVABLE_DIRECTORY)) 1158 if (isTop(DirectoryModel.REMOVABLE_DIRECTORY))
1140 return DirectoryModel.RootType.REMOVABLE; 1159 return DirectoryModel.RootType.REMOVABLE;
1141 return ''; 1160 return '';
1142 }; 1161 };
1143 1162
1144 /** 1163 /**
1145 * @param {string} path 1164 * @param {string} path
1146 * @return {boolean} 1165 * @return {boolean}
1147 */ 1166 */
1148 DirectoryModel.isRootPath = function(path) { 1167 DirectoryModel.isRootPath = function(path) {
1149 if (path[path.length - 1] == '/') 1168 if (path[path.length - 1] == '/')
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1241 /** 1260 /**
1242 * @private 1261 * @private
1243 */ 1262 */
1244 DirectoryModel.Scanner.prototype.recordMetrics_ = function() { 1263 DirectoryModel.Scanner.prototype.recordMetrics_ = function() {
1245 metrics.recordInterval('DirectoryScan'); 1264 metrics.recordInterval('DirectoryScan');
1246 if (this.dir_.fullPath == 1265 if (this.dir_.fullPath ==
1247 '/' + DirectoryModel.DOWNLOADS_DIRECTORY) { 1266 '/' + DirectoryModel.DOWNLOADS_DIRECTORY) {
1248 metrics.recordMediumCount('DownloadsCount', this.list_.length); 1267 metrics.recordMediumCount('DownloadsCount', this.list_.length);
1249 } 1268 }
1250 }; 1269 };
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