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