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

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

Issue 10201018: Revert 133663 - 1. Fix JSDocs in directory_model.js. (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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 43
44 /** 44 /**
45 * A map root.fullPath -> currentDirectory.fullPath. 45 * A map root.fullPath -> currentDirectory.fullPath.
46 * @private 46 * @private
47 * @type {Object.<string, string>} 47 * @type {Object.<string, string>}
48 */ 48 */
49 this.currentDirByRoot_ = {}; 49 this.currentDirByRoot_ = {};
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.filterHidden = true;
54 54
55 // Readonly status. 55 // Readonly status.
56 this.readonly_ = false; 56 this.readonly_ = false;
57 this.currentVolumeMetadata_ = {rootPath: '/'}; 57 this.currentVolumeMetadata_ = {rootPath: '/'};
58 this.offline_ = false; 58 this.offline_ = false;
59 } 59 }
60 60
61 /** 61 /**
62 * The name of the directory containing externally 62 * The name of the directory containing externally
63 * mounted removable storage volumes. 63 * mounted removable storage volumes.
(...skipping 20 matching lines...) Expand all
84 /** 84 /**
85 * The name of the downloads directory. 85 * The name of the downloads directory.
86 */ 86 */
87 DirectoryModel.DOWNLOADS_DIRECTORY = 'Downloads'; 87 DirectoryModel.DOWNLOADS_DIRECTORY = 'Downloads';
88 88
89 /** 89 /**
90 * The name of the gdata provider directory. 90 * The name of the gdata provider directory.
91 */ 91 */
92 DirectoryModel.GDATA_DIRECTORY = 'gdata'; 92 DirectoryModel.GDATA_DIRECTORY = 'gdata';
93 93
94 /** 94 DirectoryModel.prototype = {
95 * DirectoryModel extends cr.EventTarget. 95 __proto__: cr.EventTarget.prototype,
96 */
97 DirectoryModel.prototype.__proto__ = cr.EventTarget.prototype;
98 96
99 /** 97 /**
100 * @return {cr.ui.ArrayDataModel} Files in the current directory. 98 * Files in the current directory.
101 */ 99 * @type {cr.ui.ArrayDataModel}
102 DirectoryModel.prototype.getFileList = function() { 100 */
103 return this.fileList_; 101 get fileList() {
104 }; 102 return this.fileList_;
103 },
105 104
106 /** 105 /**
107 * Sort the file list. 106 * Selection in the fileList.
108 * @param {string} sortField Sort field. 107 * @type {cr.ui.ListSelectionModel|cr.ui.ListSingleSelectionModel}
109 * @param {string} sortDirection "asc" or "desc". 108 */
110 */ 109 get fileListSelection() {
111 DirectoryModel.prototype.sortFileList = function(sortField, sortDirection) { 110 return this.fileListSelection_;
112 this.fileList_.sort(sortField, sortDirection); 111 },
113 };
114 112
115 /** 113 get rootType() {
116 * @return {cr.ui.ListSelectionModel|cr.ui.ListSingleSelectionModel} Selection 114 return DirectoryModel.getRootType(this.currentEntry.fullPath);
117 * in the fileList. 115 },
118 */
119 DirectoryModel.prototype.getFileListSelection = function() {
120 return this.fileListSelection_;
121 };
122 116
123 /** 117 get rootName() {
124 * @return {DirectoryModel.RootType} Root type of current root. 118 return DirectoryModel.getRootName(this.currentEntry.fullPath);
125 */ 119 },
126 DirectoryModel.prototype.getRootType = function() {
127 return DirectoryModel.getRootType(this.currentDirEntry_.fullPath);
128 };
129 120
130 /** 121 /**
131 * @return {string} Root name. 122 * True if current directory is read only.
132 */ 123 * @type {boolean}
133 DirectoryModel.prototype.getRootName = function() { 124 */
134 return DirectoryModel.getRootName(this.currentDirEntry_.fullPath); 125 get readonly() {
135 }; 126 return this.readonly_;
127 },
136 128
137 /** 129 get offline() {
138 * @return {boolean} True if current directory is read only. 130 return this.offline_;
139 */ 131 },
140 DirectoryModel.prototype.isReadOnly = function() { 132 set offline(value) {
141 return this.readonly_; 133 if (this.offline_ != value) {
142 }; 134 this.offline_ = !!value;
135 this.updateReadonlyStatus_();
136 }
137 },
143 138
144 /** 139 get isSystemDirectoy() {
145 * @return {boolean} If offline. 140 var path = this.currentEntry.fullPath;
146 */ 141 return path == '/' ||
147 DirectoryModel.prototype.isOffline = function() { 142 path == '/' + DirectoryModel.REMOVABLE_DIRECTORY ||
148 return this.offline_; 143 path == '/' + DirectoryModel.ARCHIVE_DIRECTORY;
149 }; 144 },
150 145
151 /** 146 get filterHidden() {
152 * @param {boolean} value New online status. 147 return !!this.filters_['hidden'];
153 */ 148 },
154 DirectoryModel.prototype.setOffline = function(value) {
155 if (this.offline_ != value) {
156 this.offline_ = !!value;
157 this.updateReadonlyStatus_();
158 }
159 };
160 149
161 /** 150 set filterHidden(value) {
162 * @return {boolean} If current directory is system. 151 if (value) {
163 */ 152 this.addFilter('hidden',
164 DirectoryModel.prototype.isSystemDirectory = function() { 153 function(e) {return e.name.substr(0, 1) != '.';});
165 var path = this.currentDirEntry_.fullPath; 154 } else {
166 return path == '/' || 155 this.removeFilter('hidden');
167 path == '/' + DirectoryModel.REMOVABLE_DIRECTORY || 156 }
168 path == '/' + DirectoryModel.ARCHIVE_DIRECTORY; 157 },
169 };
170 158
171 /** 159 /**
172 * @return {boolean} If the files with names starting with "." are not shown. 160 * Current directory.
173 */ 161 * @type {DirectoryEntry}
174 DirectoryModel.prototype.isFilterHiddenOn = function() { 162 */
175 return !!this.filters_['hidden']; 163 get currentEntry() {
176 }; 164 return this.currentDirEntry_;
165 },
177 166
178 /** 167 set autoSelectIndex(value) {
179 * @param {boolean} value Whether files with leading "." are hidden. 168 this.autoSelectIndex_ = value;
180 */ 169 },
181 DirectoryModel.prototype.setFilterHidden = function(value) {
182 if (value) {
183 this.addFilter('hidden',
184 function(e) {return e.name.substr(0, 1) != '.';});
185 } else {
186 this.removeFilter('hidden');
187 }
188 };
189 170
190 /** 171 /**
191 * @return {DirectoryEntry} Current directory. 172 * Names of selected files.
192 */ 173 * @type {Array.<string>}
193 DirectoryModel.prototype.getCurrentDirEntry = function() { 174 */
194 return this.currentDirEntry_; 175 get selectedNames() {
195 }; 176 var indexes = this.fileListSelection_.selectedIndexes;
177 var dataModel = this.fileList_;
178 if (dataModel) {
179 return indexes.map(function(i) {
180 return dataModel.item(i).name;
181 });
182 }
183 return [];
184 },
196 185
197 /** 186 set selectedNames(value) {
198 * @private 187 var indexes = [];
199 * @return {Array.<string>} Names of selected files. 188 var dataModel = this.fileList_;
200 */
201 DirectoryModel.prototype.getSelectedNames_ = function() {
202 var indexes = this.fileListSelection_.selectedIndexes;
203 var dataModel = this.fileList_;
204 if (dataModel) {
205 return indexes.map(function(i) {
206 return dataModel.item(i).name;
207 });
208 }
209 return [];
210 };
211 189
212 /** 190 function safeKey(key) {
213 * @private 191 // The transformation must:
214 * @param {Array.<string>} value List of names of selected files. 192 // 1. Never generate a reserved name ('__proto__')
215 */ 193 // 2. Keep different keys different.
216 DirectoryModel.prototype.setSelectedNames_ = function(value) { 194 return '#' + key;
217 var indexes = []; 195 }
218 var dataModel = this.fileList_;
219 196
220 function safeKey(key) { 197 var hash = {};
221 // The transformation must:
222 // 1. Never generate a reserved name ('__proto__')
223 // 2. Keep different keys different.
224 return '#' + key;
225 }
226 198
227 var hash = {}; 199 for (var i = 0; i < value.length; i++)
200 hash[safeKey(value[i])] = 1;
228 201
229 for (var i = 0; i < value.length; i++) 202 for (var i = 0; i < dataModel.length; i++) {
230 hash[safeKey(value[i])] = 1; 203 if (hash.hasOwnProperty(safeKey(dataModel.item(i).name)))
204 indexes.push(i);
205 }
206 this.fileListSelection_.selectedIndexes = indexes;
207 },
231 208
232 for (var i = 0; i < dataModel.length; i++) { 209 /**
233 if (hash.hasOwnProperty(safeKey(dataModel.item(i).name))) 210 * Lead item file name.
234 indexes.push(i); 211 * @type {string?}
235 } 212 */
236 this.fileListSelection_.selectedIndexes = indexes; 213 get leadName() {
237 }; 214 var index = this.fileListSelection_.leadIndex;
215 return index >= 0 && this.fileList_.item(index).name;
216 },
238 217
239 /** 218 set leadName(value) {
240 * @private 219 for (var i = 0; i < this.fileList_.length; i++) {
241 * @return {string} Lead item file name. 220 if (this.fileList_.item(i).name == value) {
242 */ 221 this.fileListSelection_.leadIndex = i;
243 DirectoryModel.prototype.getLeadName_ = function() { 222 return;
244 var index = this.fileListSelection_.leadIndex; 223 }
245 return index >= 0 && this.fileList_.item(index).name;
246 };
247
248 /**
249 * @private
250 * @param {string} value The name of new lead index.
251 */
252 DirectoryModel.prototype.setLeadName_ = function(value) {
253 for (var i = 0; i < this.fileList_.length; i++) {
254 if (this.fileList_.item(i).name == value) {
255 this.fileListSelection_.leadIndex = i;
256 return;
257 } 224 }
258 } 225 }
259 }; 226 };
260 227
261 /** 228 /**
262 * @return {cr.ui.ArrayDataModel} The list of roots. 229 * @return {cr.ui.ArrayDataModel} The list of roots.
263 */ 230 */
264 DirectoryModel.prototype.getRootsList = function() { 231 DirectoryModel.prototype.getRootsList = function() {
265 return this.rootsList_; 232 return this.rootsList_;
266 }; 233 };
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 this.pendingScan_ = this.createScanner_(fileList, successCallback); 327 this.pendingScan_ = this.createScanner_(fileList, successCallback);
361 return; 328 return;
362 } 329 }
363 330
364 this.runningScan_ = this.createScanner_(fileList, successCallback); 331 this.runningScan_ = this.createScanner_(fileList, successCallback);
365 this.runningScan_.run(); 332 this.runningScan_.run();
366 }; 333 };
367 334
368 /** 335 /**
369 * @private 336 * @private
370 * @param {Array.<Entry>|cr.ui.ArrayDataModel} list File list. 337 * @param {Array.<Entry>|cr.ui.ArrayDataModel} list
371 * @param {function} successCallback Callback on success. 338 * @param {function} successCallback Callback on success.
372 * @return {DirectoryModel.Scanner} New Scanner instance. 339 * @return {DirectoryModel.Scanner} New Scanner instance.
373 */ 340 */
374 DirectoryModel.prototype.createScanner_ = function(list, successCallback) { 341 DirectoryModel.prototype.createScanner_ = function(list, successCallback) {
375 var self = this; 342 var self = this;
376 function onSuccess() { 343 function onSuccess() {
377 self.scanFailures_ = 0; 344 self.scanFailures_ = 0;
378 successCallback(); 345 successCallback();
379 if (self.pendingScan_) { 346 if (self.pendingScan_) {
380 self.runningScan_ = self.pendingScan_; 347 self.runningScan_ = self.pendingScan_;
(...skipping 14 matching lines...) Expand all
395 this.currentDirEntry_, 362 this.currentDirEntry_,
396 list, 363 list,
397 onSuccess, 364 onSuccess,
398 onFailure, 365 onFailure,
399 this.prefetchCacheForSorting_.bind(this), 366 this.prefetchCacheForSorting_.bind(this),
400 this.filters_); 367 this.filters_);
401 }; 368 };
402 369
403 /** 370 /**
404 * @private 371 * @private
405 * @param {Array.<Entry>} entries List of files. 372 * @param {Array.<Entry>} entries
406 */ 373 */
407 DirectoryModel.prototype.replaceFileList_ = function(entries) { 374 DirectoryModel.prototype.replaceFileList_ = function(entries) {
408 cr.dispatchSimpleEvent(this, 'begin-update-files'); 375 cr.dispatchSimpleEvent(this, 'begin-update-files');
409 this.fileListSelection_.beginChange(); 376 this.fileListSelection_.beginChange();
410 377
411 var selectedNames = this.getSelectedNames_(); 378 var selectedNames = this.selectedNames;
412 // Restore leadIndex in case leadName no longer exists. 379 // Restore leadIndex in case leadName no longer exists.
413 var leadIndex = this.fileListSelection_.leadIndex; 380 var leadIndex = this.fileListSelection_.leadIndex;
414 var leadName = this.getLeadName_(); 381 var leadName = this.leadName;
415 382
416 var spliceArgs = [].slice.call(entries); 383 var spliceArgs = [].slice.call(entries);
417 spliceArgs.unshift(0, this.fileList_.length); 384 spliceArgs.unshift(0, this.fileList_.length);
418 this.fileList_.splice.apply(this.fileList_, spliceArgs); 385 this.fileList_.splice.apply(this.fileList_, spliceArgs);
419 386
420 this.setSelectedNames_(selectedNames); 387 this.selectedNames = selectedNames;
421 this.fileListSelection_.leadIndex = leadIndex; 388 this.fileListSelection_.leadIndex = leadIndex;
422 this.setLeadName_(leadName); 389 this.leadName = leadName;
423 this.fileListSelection_.endChange(); 390 this.fileListSelection_.endChange();
424 cr.dispatchSimpleEvent(this, 'end-update-files'); 391 cr.dispatchSimpleEvent(this, 'end-update-files');
425 }; 392 };
426 393
427 /** 394 /**
428 * Cancels waiting and scheduled rescans and starts new scan. 395 * Cancels waiting and scheduled rescans and starts new scan.
429 * 396 *
430 * If the scan completes successfully on the first attempt, the callback will 397 * If the scan completes successfully on the first attempt, the callback will
431 * be invoked and a 'scan-completed' event will be dispatched. If the scan 398 * be invoked and a 'scan-completed' event will be dispatched. If the scan
432 * fails for any reason, we'll periodically retry until it succeeds (and then 399 * fails for any reason, we'll periodically retry until it succeeds (and then
(...skipping 26 matching lines...) Expand all
459 if (this.currentDirEntry_ == this.unmountedGDataEntry_) { 426 if (this.currentDirEntry_ == this.unmountedGDataEntry_) {
460 onDone(); 427 onDone();
461 return; 428 return;
462 } 429 }
463 this.runningScan_ = this.createScanner_(this.fileList_, onDone); 430 this.runningScan_ = this.createScanner_(this.fileList_, onDone);
464 this.runningScan_.run(); 431 this.runningScan_.run();
465 }; 432 };
466 433
467 /** 434 /**
468 * @private 435 * @private
469 * @param {Array.<Entry>} entries Files. 436 * @param {Array.<Entry>} entries
470 * @param {function} callback Callback on done. 437 * @param {function} callback
471 */ 438 */
472 DirectoryModel.prototype.prefetchCacheForSorting_ = function(entries, 439 DirectoryModel.prototype.prefetchCacheForSorting_ = function(entries,
473 callback) { 440 callback) {
474 var field = this.fileList_.sortStatus.field; 441 var field = this.fileList_.sortStatus.field;
475 if (field) { 442 if (field) {
476 this.prepareSortEntries_(entries, field, callback); 443 this.prepareSortEntries_(entries, field, callback);
477 } else { 444 } else {
478 callback(); 445 callback();
479 } 446 }
480 }; 447 };
(...skipping 25 matching lines...) Expand all
506 473
507 util.removeFileOrDirectory( 474 util.removeFileOrDirectory(
508 entry, 475 entry,
509 onSuccess, 476 onSuccess,
510 util.flog('Error deleting ' + entry.fullPath, onComplete)); 477 util.flog('Error deleting ' + entry.fullPath, onComplete));
511 } 478 }
512 onComplete(); 479 onComplete();
513 }; 480 };
514 481
515 /** 482 /**
516 * @param {string} name Filename. 483 * @param {string} name
517 */ 484 */
518 DirectoryModel.prototype.onEntryChanged = function(name) { 485 DirectoryModel.prototype.onEntryChanged = function(name) {
519 var currentEntry = this.currentDirEntry_; 486 var currentEntry = this.currentEntry;
520 var dm = this.fileList_; 487 var dm = this.fileList_;
521 var self = this; 488 var self = this;
522 489
523 function onEntryFound(entry) { 490 function onEntryFound(entry) {
524 self.prefetchCacheForSorting_([entry], function() { 491 self.prefetchCacheForSorting_([entry], function() {
525 // Do nothing if current directory changed during async operations. 492 // Do nothing if current directory changed during async operations.
526 if (self.currentDirEntry_ != currentEntry) 493 if (self.currentEntry != currentEntry)
527 return; 494 return;
528 495
529 var index = self.findIndexByName_(name); 496 var index = self.findIndexByName_(name);
530 if (index >= 0) 497 if (index >= 0)
531 dm.splice(index, 1, entry); 498 dm.splice(index, 1, entry);
532 else 499 else
533 dm.splice(dm.length, 0, entry); 500 dm.splice(dm.length, 0, entry);
534 }); 501 });
535 }; 502 };
536 503
537 function onError(err) { 504 function onError(err) {
538 // Do nothing if current directory changed during async operations. 505 // Do nothing if current directory changed during async operations.
539 if (self.currentDirEntry_ != currentEntry) 506 if (self.currentEntry != currentEntry)
540 return; 507 return;
541 if (err.code != FileError.NOT_FOUND_ERR) { 508 if (err.code != FileError.NOT_FOUND_ERR) {
542 self.rescanLater(); 509 self.rescanLater();
543 return; 510 return;
544 } 511 }
545 512
546 var index = self.findIndexByName_(name); 513 var index = self.findIndexByName_(name);
547 if (index >= 0) 514 if (index >= 0)
548 dm.splice(index, 1); 515 dm.splice(index, 1);
549 }; 516 };
550 517
551 util.resolvePath(this.currentDirEntry_, name, onEntryFound, onError); 518 util.resolvePath(currentEntry, name, onEntryFound, onError);
552 }; 519 };
553 520
554 /** 521 /**
555 * @private 522 * @private
556 * @param {string} name Filename. 523 * @param {string} name
557 * @return {number} The index in the fileList. 524 * @return {number} The index in the fileList.
558 */ 525 */
559 DirectoryModel.prototype.findIndexByName_ = function(name) { 526 DirectoryModel.prototype.findIndexByName_ = function(name) {
560 var dm = this.fileList_; 527 var dm = this.fileList_;
561 for (var i = 0; i < dm.length; i++) 528 for (var i = 0; i < dm.length; i++)
562 if (dm.item(i).name == name) 529 if (dm.item(i).name == name)
563 return i; 530 return i;
564 return -1; 531 return -1;
565 }; 532 };
566 533
567 /** 534 /**
568 * Rename the entry in the filesystem and update the file list. 535 * Rename the entry in the filesystem and update the file list.
569 * @param {Entry} entry Entry to rename. 536 * @param {Entry} entry Entry to rename.
570 * @param {string} newName New name. 537 * @param {string} newName
571 * @param {function} errorCallback Called on error. 538 * @param {function} errorCallback Called on error.
572 * @param {function} opt_successCallback Called on success. 539 * @param {function} opt_successCallback Called on success.
573 */ 540 */
574 DirectoryModel.prototype.renameEntry = function(entry, newName, errorCallback, 541 DirectoryModel.prototype.renameEntry = function(entry, newName, errorCallback,
575 opt_successCallback) { 542 opt_successCallback) {
576 var self = this; 543 var self = this;
577 function onSuccess(newEntry) { 544 function onSuccess(newEntry) {
578 self.prefetchCacheForSorting_([newEntry], function() { 545 self.prefetchCacheForSorting_([newEntry], function() {
579 var fileList = self.fileList_; 546 var fileList = self.fileList_;
580 var index = fileList.indexOf(entry); 547 var index = fileList.indexOf(entry);
581 if (index >= 0) 548 if (index >= 0)
582 fileList.splice(index, 1, newEntry); 549 fileList.splice(index, 1, newEntry);
583 self.selectEntry(newName); 550 self.selectEntry(newName);
584 // If the entry doesn't exist in the list it mean that it updated from 551 // If the entry doesn't exist in the list it mean that it updated from
585 // outside (probably by directory rescan). 552 // outside (probably by directory rescan).
586 if (opt_successCallback) 553 if (opt_successCallback)
587 opt_successCallback(); 554 opt_successCallback();
588 }); 555 });
589 } 556 }
590 entry.moveTo(this.currentDirEntry_, newName, onSuccess, errorCallback); 557 entry.moveTo(this.currentEntry, newName,
558 onSuccess, errorCallback);
591 }; 559 };
592 560
593 /** 561 /**
594 * Checks if current directory contains a file or directory with this name. 562 * Checks if current directory contains a file or directory with this name.
595 * @param {string} newName Name to check. 563 * @param {string} newName Name to check.
596 * @param {function(boolean, boolean?)} callback Called when the result's 564 * @param {function(boolean, boolean?)} callback Called when the result's
597 * available. First parameter is true if the entry exists and second 565 * available. First parameter is true if the entry exists and second
598 * is true if it's a file. 566 * is true if it's a file.
599 */ 567 */
600 DirectoryModel.prototype.doesExist = function(newName, callback) { 568 DirectoryModel.prototype.doesExist = function(newName, callback) {
601 util.resolvePath(this.currentDirEntry_, newName, 569 util.resolvePath(this.currentEntry, newName,
602 function(entry) { 570 function(entry) {
603 callback(true, entry.isFile); 571 callback(true, entry.isFile);
604 }, 572 },
605 callback.bind(window, false)); 573 callback.bind(window, false));
606 }; 574 };
607 575
608 /** 576 /**
609 * Creates directory and updates the file list. 577 * Creates directory and updates the file list.
610 * 578 *
611 * @param {string} name Directory name. 579 * @param {string} name
612 * @param {function} successCallback Callback on success. 580 * @param {function} successCallback
613 * @param {function} errorCallback Callback on failure. 581 * @param {function} errorCallback
614 */ 582 */
615 DirectoryModel.prototype.createDirectory = function(name, successCallback, 583 DirectoryModel.prototype.createDirectory = function(name, successCallback,
616 errorCallback) { 584 errorCallback) {
617 var self = this; 585 var self = this;
618 function onSuccess(newEntry) { 586 function onSuccess(newEntry) {
619 self.prefetchCacheForSorting_([newEntry], function() { 587 self.prefetchCacheForSorting_([newEntry], function() {
620 var fileList = self.fileList_; 588 var fileList = self.fileList_;
621 var existing = fileList.slice().filter( 589 var existing = fileList.slice().filter(
622 function(e) { return e.name == name; }); 590 function(e) { return e.name == name; });
623 591
624 if (existing.length) { 592 if (existing.length) {
625 self.selectEntry(name); 593 self.selectEntry(name);
626 successCallback(existing[0]); 594 successCallback(existing[0]);
627 } else { 595 } else {
628 self.fileListSelection_.beginChange(); 596 self.fileListSelection.beginChange();
629 fileList.splice(0, 0, newEntry); 597 fileList.splice(0, 0, newEntry);
630 self.selectEntry(name); 598 self.selectEntry(name);
631 self.fileListSelection_.endChange(); 599 self.fileListSelection.endChange();
632 successCallback(newEntry); 600 successCallback(newEntry);
633 } 601 }
634 }); 602 });
635 } 603 }
636 604
637 this.currentDirEntry_.getDirectory(name, {create: true, exclusive: true}, 605 this.currentEntry.getDirectory(name, {create: true, exclusive: true},
638 onSuccess, errorCallback); 606 onSuccess, errorCallback);
639 }; 607 };
640 608
641 /** 609 /**
642 * Changes directory. Causes 'directory-change' event. 610 * Changes directory. Causes 'directory-change' event.
643 * 611 *
644 * @param {string} path New current directory path. 612 * @param {string} path New current directory path.
645 * @param {function} opt_OnError Called if failed. 613 * @param {function} opt_OnError Called if failed.
646 */ 614 */
647 DirectoryModel.prototype.changeDirectory = function(path, opt_OnError) { 615 DirectoryModel.prototype.changeDirectory = function(path, opt_OnError) {
648 var onDirectoryResolved = this.changeDirectoryEntry_.bind(this, false); 616 var onDirectoryResolved = this.changeDirectoryEntry_.bind(this, false);
(...skipping 29 matching lines...) Expand all
678 * 646 *
679 * Dispatches the 'directory-changed' event when the directory is successfully 647 * Dispatches the 'directory-changed' event when the directory is successfully
680 * changed. 648 * changed.
681 * 649 *
682 * @private 650 * @private
683 * @param {boolean} initial True if it comes from setupPath and 651 * @param {boolean} initial True if it comes from setupPath and
684 * false if caused by an user action. 652 * false if caused by an user action.
685 * @param {DirectoryEntry} dirEntry A new directory entry. 653 * @param {DirectoryEntry} dirEntry A new directory entry.
686 */ 654 */
687 DirectoryModel.prototype.changeDirectoryEntry_ = function(initial, dirEntry) { 655 DirectoryModel.prototype.changeDirectoryEntry_ = function(initial, dirEntry) {
688 var previous = this.currentDirEntry_; 656 var previous = this.currentEntry;
689 this.currentDirEntry_ = dirEntry; 657 this.currentDirEntry_ = dirEntry;
690 function onRescanComplete() { 658 function onRescanComplete() {
691 // For tests that open the dialog to empty directories, everything 659 // For tests that open the dialog to empty directories, everything
692 // is loaded at this point. 660 // is loaded at this point.
693 chrome.test.sendMessage('directory-change-complete'); 661 chrome.test.sendMessage('directory-change-complete');
694 } 662 }
695 this.updateReadonlyStatus_(); 663 this.updateReadonlyStatus_();
696 this.updateVolumeMetadata_(); 664 this.updateVolumeMetadata_();
697 this.updateRootsListSelection_(); 665 this.updateRootsListSelection_();
698 this.scan_(onRescanComplete); 666 this.scan_(onRescanComplete);
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 onLeafError.bind(this, baseDirEntry)); 778 onLeafError.bind(this, baseDirEntry));
811 }.bind(this); 779 }.bind(this);
812 780
813 var root = this.root_; 781 var root = this.root_;
814 if (!baseName) 782 if (!baseName)
815 baseName = this.getDefaultDirectory(); 783 baseName = this.getDefaultDirectory();
816 root.getDirectory(baseName, {create: false}, onBaseFound, onBaseError); 784 root.getDirectory(baseName, {create: false}, onBaseFound, onBaseError);
817 }; 785 };
818 786
819 /** 787 /**
820 * @param {function} opt_callback Callback on done. 788 * @param {function} opt_callback
821 */ 789 */
822 DirectoryModel.prototype.setupDefaultPath = function(opt_callback) { 790 DirectoryModel.prototype.setupDefaultPath = function(opt_callback) {
823 this.setupPath(this.getDefaultDirectory(), opt_callback); 791 var overridden = false;
792 function onExternalDirChange() { overridden = true }
793 this.addEventListener('directory-changed', onExternalDirChange);
794
795 this.getDefaultDirectory_(function(path) {
796 this.removeEventListener('directory-changed', onExternalDirChange);
797 if (!overridden)
798 this.setupPath(path, opt_callback);
799 }.bind(this));
824 }; 800 };
825 801
826 /** 802 /**
827 * @return {string} The default directory. 803 * @private
804 * @param {function} callback
828 */ 805 */
829 DirectoryModel.prototype.getDefaultDirectory = function() { 806 DirectoryModel.prototype.getDefaultDirectory = function() {
830 return '/' + DirectoryModel.DOWNLOADS_DIRECTORY; 807 return '/' + DirectoryModel.DOWNLOADS_DIRECTORY;
831 }; 808 };
832 809
833 /** 810 /**
834 * @param {string} name Filename. 811 * @param {string} name
835 */ 812 */
836 DirectoryModel.prototype.selectEntry = function(name) { 813 DirectoryModel.prototype.selectEntry = function(name) {
837 var dm = this.fileList_; 814 var dm = this.fileList_;
838 for (var i = 0; i < dm.length; i++) { 815 for (var i = 0; i < dm.length; i++) {
839 if (dm.item(i).name == name) { 816 if (dm.item(i).name == name) {
840 this.selectIndex(i); 817 this.selectIndex(i);
841 return; 818 return;
842 } 819 }
843 } 820 }
844 }; 821 };
845 822
846 /** 823 /**
847 * @param {number} index Index of file. 824 * @param {number} index
848 */ 825 */
849 DirectoryModel.prototype.selectIndex = function(index) { 826 DirectoryModel.prototype.selectIndex = function(index) {
850 // this.focusCurrentList_(); 827 // this.focusCurrentList_();
851 if (index >= this.fileList_.length) 828 if (index >= this.fileList_.length)
852 return; 829 return;
853 830
854 // If a list bound with the model it will do scrollIndexIntoView(index). 831 // If a list bound with the model it will do scrollIndexIntoView(index).
855 this.fileListSelection_.selectedIndex = index; 832 this.fileListSelection_.selectedIndex = index;
856 }; 833 };
857 834
858 /** 835 /**
859 * Cache necessary data before a sort happens. 836 * Cache necessary data before a sort happens.
860 * 837 *
861 * This is called by the table code before a sort happens, so that we can 838 * This is called by the table code before a sort happens, so that we can
862 * go fetch data for the sort field that we may not have yet. 839 * go fetch data for the sort field that we may not have yet.
863 * @private 840 * @private
864 * @param {string} field Sort field. 841 * @param {string} field
865 * @param {function} callback Called when done. 842 * @param {function} callback
866 */ 843 */
867 DirectoryModel.prototype.prepareSort_ = function(field, callback) { 844 DirectoryModel.prototype.prepareSort_ = function(field, callback) {
868 this.prepareSortEntries_(this.fileList_.slice(), field, callback); 845 this.prepareSortEntries_(this.fileList_.slice(), field, callback);
869 }; 846 };
870 847
871 /** 848 /**
872 * @private 849 * @private
873 * @param {Array.<Entry>} entries Files. 850 * @param {Array.<Entry>} entries
874 * @param {string} field Sort field. 851 * @param {string} field
875 * @param {function} callback Called when done. 852 * @param {function} callback
876 */ 853 */
877 DirectoryModel.prototype.prepareSortEntries_ = function(entries, field, 854 DirectoryModel.prototype.prepareSortEntries_ = function(entries, field,
878 callback) { 855 callback) {
879 this.metadataCache_.get(entries, 'filesystem', function(properties) { 856 this.metadataCache_.get(entries, 'filesystem', function(properties) {
880 callback(); 857 callback();
881 }); 858 });
882 }; 859 };
883 860
884 /** 861 /**
885 * Get root entries asynchronously. 862 * Get root entries asynchronously.
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1019 */ 996 */
1020 DirectoryModel.prototype.updateRootsListSelection_ = function() { 997 DirectoryModel.prototype.updateRootsListSelection_ = function() {
1021 var rootPath = DirectoryModel.getRootPath(this.currentDirEntry_.fullPath); 998 var rootPath = DirectoryModel.getRootPath(this.currentDirEntry_.fullPath);
1022 this.rootsListSelection_.selectedIndex = this.findRootsListItem_(rootPath); 999 this.rootsListSelection_.selectedIndex = this.findRootsListItem_(rootPath);
1023 }; 1000 };
1024 1001
1025 /** 1002 /**
1026 * @private 1003 * @private
1027 */ 1004 */
1028 DirectoryModel.prototype.updateReadonlyStatus_ = function() { 1005 DirectoryModel.prototype.updateReadonlyStatus_ = function() {
1029 switch (this.getRootType()) { 1006 switch (this.rootType) {
1030 case DirectoryModel.RootType.REMOVABLE: 1007 case DirectoryModel.RootType.REMOVABLE:
1031 this.readonly_ = !!this.currentVolumeMetadata_.isReadOnly; 1008 this.readonly_ = !!this.currentVolumeMetadata_.isReadOnly;
1032 break; 1009 break;
1033 case DirectoryModel.RootType.ARCHIVE: 1010 case DirectoryModel.RootType.ARCHIVE:
1034 this.readonly_ = true; 1011 this.readonly_ = true;
1035 break; 1012 break;
1036 case DirectoryModel.RootType.DOWNLOADS: 1013 case DirectoryModel.RootType.DOWNLOADS:
1037 this.readonly_ = false; 1014 this.readonly_ = false;
1038 break; 1015 break;
1039 case DirectoryModel.RootType.GDATA: 1016 case DirectoryModel.RootType.GDATA:
1040 this.readonly_ = this.offline_; 1017 this.readonly_ = this.offline;
1041 break; 1018 break;
1042 default: 1019 default:
1043 this.readonly_ = true; 1020 this.readonly_ = true;
1044 break; 1021 break;
1045 } 1022 }
1046 }; 1023 };
1047 1024
1048 /** 1025 /**
1049 * @private 1026 * @private
1050 */ 1027 */
(...skipping 13 matching lines...) Expand all
1064 } 1041 }
1065 }); 1042 });
1066 }); 1043 });
1067 } 1044 }
1068 } 1045 }
1069 }; 1046 };
1070 1047
1071 /** 1048 /**
1072 * Prepare the root for the unmount. 1049 * Prepare the root for the unmount.
1073 * 1050 *
1074 * @param {string} rootPath The path to the root. 1051 * @param {string} rootPath
1075 */ 1052 */
1076 DirectoryModel.prototype.prepareUnmount = function(rootPath) { 1053 DirectoryModel.prototype.prepareUnmount = function(rootPath) {
1077 var index = this.findRootsListItem_(rootPath); 1054 var index = this.findRootsListItem_(rootPath);
1078 if (index == -1) { 1055 if (index == -1) {
1079 console.error('Unknown root entry', rootPath); 1056 console.error('Unknown root entry', rootPath);
1080 return; 1057 return;
1081 } 1058 }
1082 var entry = this.rootsList_.item(index); 1059 var entry = this.rootsList_.item(index);
1083 1060
1084 // We never need to remove this attribute because even if the unmount fails 1061 // We never need to remove this attribute because even if the unmount fails
1085 // the onMountCompleted handler calls updateRoots which creates a new entry 1062 // the onMountCompleted handler calls updateRoots which creates a new entry
1086 // object for this volume. 1063 // object for this volume.
1087 entry.unmounting = true; 1064 entry.unmounting = true;
1088 1065
1089 // Re-place the entry into the roots data model to force re-rendering. 1066 // Re-place the entry into the roots data model to force re-rendering.
1090 this.rootsList_.splice(index, 1, entry); 1067 this.rootsList_.splice(index, 1, entry);
1091 1068
1092 if (rootPath == this.rootPath) { 1069 if (rootPath == this.rootPath) {
1093 // TODO(kaznacheev): Consider changing to the most recently used root. 1070 // TODO(kaznacheev): Consider changing to the most recently used root.
1094 this.changeDirectory(this.getDefaultDirectory()); 1071 this.changeDirectory(this.getDefaultDirectory());
1095 } 1072 }
1096 }; 1073 };
1097 1074
1098 /** 1075 /**
1099 * @param {string} path Any path. 1076 * @param {string} path
1100 * @return {string} The root path. 1077 * @return {string} The root path.
1101 */ 1078 */
1102 DirectoryModel.getRootPath = function(path) { 1079 DirectoryModel.getRootPath = function(path) {
1103 var type = DirectoryModel.getRootType(path); 1080 var type = DirectoryModel.getRootType(path);
1104 1081
1105 if (type == DirectoryModel.RootType.DOWNLOADS) 1082 if (type == DirectoryModel.RootType.DOWNLOADS)
1106 return '/' + DirectoryModel.DOWNLOADS_DIRECTORY; 1083 return '/' + DirectoryModel.DOWNLOADS_DIRECTORY;
1107 if (type == DirectoryModel.RootType.GDATA) 1084 if (type == DirectoryModel.RootType.GDATA)
1108 return '/' + DirectoryModel.GDATA_DIRECTORY; 1085 return '/' + DirectoryModel.GDATA_DIRECTORY;
1109 1086
1110 function subdir(dir) { 1087 function subdir(dir) {
1111 var end = path.indexOf('/', dir.length + 2); 1088 var end = path.indexOf('/', dir.length + 2);
1112 return end == -1 ? path : path.substr(0, end); 1089 return end == -1 ? path : path.substr(0, end);
1113 } 1090 }
1114 1091
1115 if (type == DirectoryModel.RootType.ARCHIVE) 1092 if (type == DirectoryModel.RootType.ARCHIVE)
1116 return subdir(DirectoryModel.ARCHIVE_DIRECTORY); 1093 return subdir(DirectoryModel.ARCHIVE_DIRECTORY);
1117 if (type == DirectoryModel.REMOVABLE_DIRECTORY) 1094 if (type == DirectoryModel.REMOVABLE_DIRECTORY)
1118 return subdir(DirectoryModel.REMOVABLE_DIRECTORY); 1095 return subdir(DirectoryModel.REMOVABLE_DIRECTORY);
1119 return '/'; 1096 return '/';
1120 }; 1097 };
1121 1098
1122 /** 1099 /**
1123 * @param {string} path Any path. 1100 * @param {string} path
1124 * @return {string} The name of the root. 1101 * @return {string}
1125 */ 1102 */
1126 DirectoryModel.getRootName = function(path) { 1103 DirectoryModel.getRootName = function(path) {
1127 var root = DirectoryModel.getRootPath(path); 1104 var root = DirectoryModel.getRootPath(path);
1128 var index = root.lastIndexOf('/'); 1105 var index = root.lastIndexOf('/');
1129 return index == -1 ? root : root.substring(index + 1); 1106 return index == -1 ? root : root.substring(index + 1);
1130 }; 1107 };
1131 1108
1132 /** 1109 /**
1133 * @param {string} path A path. 1110 * @param {string} path Path.
1134 * @return {string} A root type. 1111 * @return {string} A root type.
1135 */ 1112 */
1136 DirectoryModel.getRootType = function(path) { 1113 DirectoryModel.getRootType = function(path) {
1137 function isTop(dir) { 1114 function isTop(dir) {
1138 return path.substr(1, dir.length) == dir; 1115 return path.substr(1, dir.length) == dir;
1139 } 1116 }
1140 1117
1141 if (isTop(DirectoryModel.DOWNLOADS_DIRECTORY)) 1118 if (isTop(DirectoryModel.DOWNLOADS_DIRECTORY))
1142 return DirectoryModel.RootType.DOWNLOADS; 1119 return DirectoryModel.RootType.DOWNLOADS;
1143 if (isTop(DirectoryModel.GDATA_DIRECTORY)) 1120 if (isTop(DirectoryModel.GDATA_DIRECTORY))
1144 return DirectoryModel.RootType.GDATA; 1121 return DirectoryModel.RootType.GDATA;
1145 if (isTop(DirectoryModel.ARCHIVE_DIRECTORY)) 1122 if (isTop(DirectoryModel.ARCHIVE_DIRECTORY))
1146 return DirectoryModel.RootType.ARCHIVE; 1123 return DirectoryModel.RootType.ARCHIVE;
1147 if (isTop(DirectoryModel.REMOVABLE_DIRECTORY)) 1124 if (isTop(DirectoryModel.REMOVABLE_DIRECTORY))
1148 return DirectoryModel.RootType.REMOVABLE; 1125 return DirectoryModel.RootType.REMOVABLE;
1149 return ''; 1126 return '';
1150 }; 1127 };
1151 1128
1152 /** 1129 /**
1153 * @param {string} path A path. 1130 * @param {string} path
1154 * @return {boolean} True if it is a path to the root. 1131 * @return {boolean}
1155 */ 1132 */
1156 DirectoryModel.isRootPath = function(path) { 1133 DirectoryModel.isRootPath = function(path) {
1157 if (path[path.length - 1] == '/') 1134 if (path[path.length - 1] == '/')
1158 path = path.substring(0, path.length - 1); 1135 path = path.substring(0, path.length - 1);
1159 return DirectoryModel.getRootPath(path) == path; 1136 return DirectoryModel.getRootPath(path) == path;
1160 }; 1137 };
1161 1138
1162 /** 1139 /**
1163 * @constructor 1140 * @constructor
1164 * @extends cr.EventTarget 1141 * @extends cr.EventTarget
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 /** 1186 /**
1210 * @private 1187 * @private
1211 */ 1188 */
1212 DirectoryModel.Scanner.prototype.readNextChunk_ = function() { 1189 DirectoryModel.Scanner.prototype.readNextChunk_ = function() {
1213 this.reader_.readEntries(this.onChunkComplete_.bind(this), 1190 this.reader_.readEntries(this.onChunkComplete_.bind(this),
1214 this.errorCallback_); 1191 this.errorCallback_);
1215 }; 1192 };
1216 1193
1217 /** 1194 /**
1218 * @private 1195 * @private
1219 * @param {Array.<Entry>} entries File list. 1196 * @param {Array.<Entry>} entries
1220 */ 1197 */
1221 DirectoryModel.Scanner.prototype.onChunkComplete_ = function(entries) { 1198 DirectoryModel.Scanner.prototype.onChunkComplete_ = function(entries) {
1222 if (this.cancelled_) 1199 if (this.cancelled_)
1223 return; 1200 return;
1224 1201
1225 if (entries.length == 0) { 1202 if (entries.length == 0) {
1226 this.successCallback_(); 1203 this.successCallback_();
1227 this.recordMetrics_(); 1204 this.recordMetrics_();
1228 return; 1205 return;
1229 } 1206 }
(...skipping 19 matching lines...) Expand all
1249 /** 1226 /**
1250 * @private 1227 * @private
1251 */ 1228 */
1252 DirectoryModel.Scanner.prototype.recordMetrics_ = function() { 1229 DirectoryModel.Scanner.prototype.recordMetrics_ = function() {
1253 metrics.recordInterval('DirectoryScan'); 1230 metrics.recordInterval('DirectoryScan');
1254 if (this.dir_.fullPath == 1231 if (this.dir_.fullPath ==
1255 '/' + DirectoryModel.DOWNLOADS_DIRECTORY) { 1232 '/' + DirectoryModel.DOWNLOADS_DIRECTORY) {
1256 metrics.recordMediumCount('DownloadsCount', this.list_.length); 1233 metrics.recordMediumCount('DownloadsCount', this.list_.length);
1257 } 1234 }
1258 }; 1235 };
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