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 /** | 5 /** |
6 * @constructor | 6 * @constructor |
7 * @param {MetadataCache} metadataCache Metadata cache service. | 7 * @param {MetadataCache} metadataCache Metadata cache service. |
8 * @param {cr.ui.ArrayDataModel} fileList The file list. | 8 * @param {cr.ui.ArrayDataModel} fileList The file list. |
9 * @param {boolean} showHidden If files starting with '.' are shown. | 9 * @param {boolean} showHidden If files starting with '.' are shown. |
10 */ | 10 */ |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 * @constructor | 83 * @constructor |
84 * @param {FileListContext} context The file list context. | 84 * @param {FileListContext} context The file list context. |
85 */ | 85 */ |
86 function DirectoryContents(context) { | 86 function DirectoryContents(context) { |
87 this.context_ = context; | 87 this.context_ = context; |
88 this.fileList_ = context.fileList; | 88 this.fileList_ = context.fileList; |
89 this.scanCompletedCallback_ = null; | 89 this.scanCompletedCallback_ = null; |
90 this.scanFailedCallback_ = null; | 90 this.scanFailedCallback_ = null; |
91 this.scanCancelled_ = false; | 91 this.scanCancelled_ = false; |
92 this.filter_ = context.filter.bind(context); | 92 this.filter_ = context.filter.bind(context); |
93 | 93 this.allChunksFetched_ = false; |
| 94 this.pendingMetadataRequests_ = 0; |
94 this.fileList_.prepareSort = this.prepareSort_.bind(this); | 95 this.fileList_.prepareSort = this.prepareSort_.bind(this); |
95 } | 96 } |
96 | 97 |
97 /** | 98 /** |
98 * DirectoryModel extends cr.EventTarget. | 99 * DirectoryModel extends cr.EventTarget. |
99 */ | 100 */ |
100 DirectoryContents.prototype.__proto__ = cr.EventTarget.prototype; | 101 DirectoryContents.prototype.__proto__ = cr.EventTarget.prototype; |
101 | 102 |
102 /** | 103 /** |
103 * Create the copy of the object, but without scan started. | 104 * Create the copy of the object, but without scan started. |
(...skipping 23 matching lines...) Expand all Loading... |
127 spliceArgs.unshift(0, fileList.length); | 128 spliceArgs.unshift(0, fileList.length); |
128 fileList.splice.apply(fileList, spliceArgs); | 129 fileList.splice.apply(fileList, spliceArgs); |
129 this.fileList_ = fileList; | 130 this.fileList_ = fileList; |
130 } | 131 } |
131 }; | 132 }; |
132 | 133 |
133 /** | 134 /** |
134 * @return {string} The path. | 135 * @return {string} The path. |
135 */ | 136 */ |
136 DirectoryContents.prototype.getPath = function() { | 137 DirectoryContents.prototype.getPath = function() { |
137 console.log((new Error()).stack); | |
138 throw 'Not implemented.'; | 138 throw 'Not implemented.'; |
139 }; | 139 }; |
140 | 140 |
141 /** | 141 /** |
| 142 * @return {boolean} If the scan is active. |
| 143 */ |
| 144 DirectoryContents.prototype.isScanning = function() { |
| 145 return !this.scanCancelled_ && |
| 146 (!this.allChunksFetched_ || this.pendingMetadataRequests_ > 0); |
| 147 }; |
| 148 |
| 149 /** |
142 * @return {boolean} True if search results (gdata or local). | 150 * @return {boolean} True if search results (gdata or local). |
143 */ | 151 */ |
144 DirectoryContents.prototype.isSearch = function() { | 152 DirectoryContents.prototype.isSearch = function() { |
145 return false; | 153 return false; |
146 }; | 154 }; |
147 | 155 |
148 /** | 156 /** |
149 * @return {DirectoryEntry} A DirectoryEntry for current directory. In case of | 157 * @return {DirectoryEntry} A DirectoryEntry for current directory. In case of |
150 * search -- the top directory from which search is run | 158 * search -- the top directory from which search is run |
151 */ | 159 */ |
(...skipping 23 matching lines...) Expand all Loading... |
175 */ | 183 */ |
176 DirectoryContents.prototype.readNextChunk = function() { | 184 DirectoryContents.prototype.readNextChunk = function() { |
177 throw 'Not implemented.'; | 185 throw 'Not implemented.'; |
178 }; | 186 }; |
179 | 187 |
180 /** | 188 /** |
181 * Cancel the running scan. | 189 * Cancel the running scan. |
182 */ | 190 */ |
183 DirectoryContents.prototype.cancelScan = function() { | 191 DirectoryContents.prototype.cancelScan = function() { |
184 this.scanCancelled_ = true; | 192 this.scanCancelled_ = true; |
| 193 cr.dispatchSimpleEvent(this, 'scan-cancelled'); |
185 }; | 194 }; |
186 | 195 |
187 | 196 |
188 /** | 197 /** |
189 * Called in case scan has failed. Should send the event. | 198 * Called in case scan has failed. Should send the event. |
190 * @protected | 199 * @protected |
191 */ | 200 */ |
192 DirectoryContents.prototype.onError = function() { | 201 DirectoryContents.prototype.onError = function() { |
193 cr.dispatchSimpleEvent(this, 'scan-failed'); | 202 cr.dispatchSimpleEvent(this, 'scan-failed'); |
194 }; | 203 }; |
195 | 204 |
196 /** | 205 /** |
197 * Called in case scan has completed succesfully. Should send the event. | 206 * Called in case scan has completed succesfully. Should send the event. |
198 * @protected | 207 * @protected |
199 */ | 208 */ |
200 DirectoryContents.prototype.onCompleted = function() { | 209 DirectoryContents.prototype.lastChunkReceived = function() { |
201 cr.dispatchSimpleEvent(this, 'scan-completed'); | 210 this.allChunksFetched_ = true; |
| 211 if (!this.scanCancelled_ && this.pendingMetadataRequests_ === 0) |
| 212 cr.dispatchSimpleEvent(this, 'scan-completed'); |
202 }; | 213 }; |
203 | 214 |
204 /** | 215 /** |
205 * Cache necessary data before a sort happens. | 216 * Cache necessary data before a sort happens. |
206 * | 217 * |
207 * This is called by the table code before a sort happens, so that we can | 218 * This is called by the table code before a sort happens, so that we can |
208 * go fetch data for the sort field that we may not have yet. | 219 * go fetch data for the sort field that we may not have yet. |
209 * @private | 220 * @private |
210 * @param {string} field Sort field. | 221 * @param {string} field Sort field. |
211 * @param {function} callback Called when done. | 222 * @param {function} callback Called when done. |
(...skipping 14 matching lines...) Expand all Loading... |
226 * @protected | 237 * @protected |
227 * @param {Array.<Entry>} entries File list. | 238 * @param {Array.<Entry>} entries File list. |
228 */ | 239 */ |
229 DirectoryContents.prototype.onNewEntries = function(entries) { | 240 DirectoryContents.prototype.onNewEntries = function(entries) { |
230 if (this.scanCancelled_) | 241 if (this.scanCancelled_) |
231 return; | 242 return; |
232 | 243 |
233 var entriesFiltered = [].filter.call(entries, this.filter_); | 244 var entriesFiltered = [].filter.call(entries, this.filter_); |
234 | 245 |
235 var onPrefetched = function() { | 246 var onPrefetched = function() { |
| 247 this.pendingMetadataRequests_--; |
236 if (this.scanCancelled_) | 248 if (this.scanCancelled_) |
237 return; | 249 return; |
238 this.fileList_.push.apply(this.fileList_, entriesFiltered); | 250 this.fileList_.push.apply(this.fileList_, entriesFiltered); |
239 this.readNextChunk(); | 251 |
| 252 if (this.pendingMetadataRequests === 0 && this.allChunksFetched_) { |
| 253 cr.dispatchSimpleEvent(this, 'scan-completed'); |
| 254 } |
| 255 |
| 256 if (!this.allChunksFetched_) |
| 257 this.readNextChunk(); |
240 }; | 258 }; |
241 | 259 |
| 260 this.pendingMetadataRequests_++; |
242 this.prefetchMetadata(entriesFiltered, onPrefetched.bind(this)); | 261 this.prefetchMetadata(entriesFiltered, onPrefetched.bind(this)); |
243 }; | 262 }; |
244 | 263 |
245 /** | 264 /** |
246 * @param {string} name Directory name. | 265 * @param {string} name Directory name. |
247 * @param {function} successCallback Called on success. | 266 * @param {function} successCallback Called on success. |
248 * @param {function} errorCallback On error. | 267 * @param {function} errorCallback On error. |
249 */ | 268 */ |
250 DirectoryContents.prototype.createDirectory = function( | 269 DirectoryContents.prototype.createDirectory = function( |
251 name, successCallback, errorCallback) { | 270 name, successCallback, errorCallback) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 | 333 |
315 /** | 334 /** |
316 * @private | 335 * @private |
317 * @param {Array.<Entry>} entries File list. | 336 * @param {Array.<Entry>} entries File list. |
318 */ | 337 */ |
319 DirectoryContentsBasic.prototype.onChunkComplete_ = function(entries) { | 338 DirectoryContentsBasic.prototype.onChunkComplete_ = function(entries) { |
320 if (this.scanCancelled_) | 339 if (this.scanCancelled_) |
321 return; | 340 return; |
322 | 341 |
323 if (entries.length == 0) { | 342 if (entries.length == 0) { |
324 this.onCompleted(); | 343 this.lastChunkReceived(); |
325 this.recordMetrics_(); | 344 this.recordMetrics_(); |
326 return; | 345 return; |
327 } | 346 } |
328 | 347 |
329 this.onNewEntries(entries); | 348 this.onNewEntries(entries); |
330 }; | 349 }; |
331 | 350 |
332 /** | 351 /** |
333 * @private | 352 * @private |
334 */ | 353 */ |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 | 448 |
430 /** | 449 /** |
431 * All the results are read in one chunk, so when we try to read second chunk, | 450 * All the results are read in one chunk, so when we try to read second chunk, |
432 * it means we're done. | 451 * it means we're done. |
433 */ | 452 */ |
434 DirectoryContentsGDataSearch.prototype.readNextChunk = function() { | 453 DirectoryContentsGDataSearch.prototype.readNextChunk = function() { |
435 if (this.scanCancelled_) | 454 if (this.scanCancelled_) |
436 return; | 455 return; |
437 | 456 |
438 if (this.done_) { | 457 if (this.done_) { |
439 this.onCompleted(); | 458 this.lastChunkReceived(); |
440 return; | 459 return; |
441 } | 460 } |
442 | 461 |
443 var searchCallback = (function(entries, nextFeed) { | 462 var searchCallback = (function(entries, nextFeed) { |
444 // TODO(tbarzic): Improve error handling. | 463 // TODO(tbarzic): Improve error handling. |
445 if (!entries) { | 464 if (!entries) { |
446 console.log('Drive search encountered an error'); | 465 console.log('Drive search encountered an error'); |
447 this.onCompleted(); | 466 this.lastChunkReceived(); |
448 return; | 467 return; |
449 } | 468 } |
450 this.nextFeed_ = nextFeed; | 469 this.nextFeed_ = nextFeed; |
451 this.fetchedResultsNum_ += entries.length; | 470 this.fetchedResultsNum_ += entries.length; |
452 if (this.fetchedResultsNum_ >= DirectoryContentsGDataSearch.MAX_RESULTS) | 471 if (this.fetchedResultsNum_ >= DirectoryContentsGDataSearch.MAX_RESULTS) |
453 this.nextFeed_ = ''; | 472 this.nextFeed_ = ''; |
454 | 473 |
455 this.done_ = (this.nextFeed_ == ''); | 474 this.done_ = (this.nextFeed_ == ''); |
456 this.onNewEntries(entries); | 475 this.onNewEntries(entries); |
457 }).bind(this); | 476 }).bind(this); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 /** | 550 /** |
532 * Scan a directory. | 551 * Scan a directory. |
533 * @param {DirectoryEntry} entry A directory to scan. | 552 * @param {DirectoryEntry} entry A directory to scan. |
534 * @private | 553 * @private |
535 */ | 554 */ |
536 DirectoryContentsLocalSearch.prototype.scanDirectory_ = function(entry) { | 555 DirectoryContentsLocalSearch.prototype.scanDirectory_ = function(entry) { |
537 this.pendingScans_++; | 556 this.pendingScans_++; |
538 var reader = entry.createReader(); | 557 var reader = entry.createReader(); |
539 var found = []; | 558 var found = []; |
540 | 559 |
541 var self = this; | |
542 | |
543 var onChunkComplete = function(entries) { | 560 var onChunkComplete = function(entries) { |
544 if (self.scanCancelled_) | 561 if (this.scanCancelled_) |
545 return; | 562 return; |
546 | 563 |
547 if (entries.length === 0) { | 564 if (entries.length === 0) { |
548 if (found.length > 0) | 565 if (found.length > 0) |
549 self.onNewEntries(found); | 566 this.onNewEntries(found); |
550 self.pendingScans_--; | 567 this.pendingScans_--; |
551 | 568 if (this.pendingScans_ === 0) |
552 if (self.pendingScans_ === 0) | 569 this.lastChunkReceived(); |
553 self.onCompleted(); | |
554 | |
555 return; | 570 return; |
556 } | 571 } |
557 | 572 |
558 for (var i = 0; i < entries.length; i++) { | 573 for (var i = 0; i < entries.length; i++) { |
559 if (entries[i].name.toLowerCase().indexOf(self.query_) != -1) { | 574 if (entries[i].name.toLowerCase().indexOf(this.query_) != -1) { |
560 found.push(entries[i]); | 575 found.push(entries[i]); |
561 } | 576 } |
562 | 577 |
563 if (entries[i].isDirectory) | 578 if (entries[i].isDirectory) |
564 self.scanDirectory_(entries[i]); | 579 this.scanDirectory_(entries[i]); |
565 } | 580 } |
566 | 581 |
567 getNextChunk(); | 582 getNextChunk(); |
568 }; | 583 }.bind(this); |
569 | 584 |
570 var getNextChunk = function() { | 585 var getNextChunk = function() { |
571 reader.readEntries(onChunkComplete, self.onError.bind(self)); | 586 reader.readEntries(onChunkComplete, this.onError.bind(this)); |
572 }; | 587 }.bind(this); |
573 | 588 |
574 getNextChunk(); | 589 getNextChunk(); |
575 }; | 590 }; |
576 | 591 |
577 /** | 592 /** |
578 * We get results for each directory in one go in scanDirectory_. | 593 * We get results for each directory in one go in scanDirectory_. |
579 */ | 594 */ |
580 DirectoryContentsLocalSearch.prototype.readNextChunk = function() { | 595 DirectoryContentsLocalSearch.prototype.readNextChunk = function() { |
581 }; | 596 }; |
OLD | NEW |