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'); | |
dgozman
2012/08/13 12:58:08
Forgot |!this.scanCacelled_|.
Maybe, create a met
Oleg Eterevsky
2012/08/13 13:32:22
scanCancelled_ checked 3 lines above. I don't want
| |
254 } else { | |
255 this.readNextChunk(); | |
dgozman
2012/08/13 13:36:48
I believe, this is called if there is pending meta
Oleg Eterevsky
2012/08/13 13:39:40
You're right. Fixed.
| |
256 } | |
240 }; | 257 }; |
241 | 258 |
259 this.pendingMetadataRequests_++; | |
242 this.prefetchMetadata(entriesFiltered, onPrefetched.bind(this)); | 260 this.prefetchMetadata(entriesFiltered, onPrefetched.bind(this)); |
243 }; | 261 }; |
244 | 262 |
245 /** | 263 /** |
246 * @param {string} name Directory name. | 264 * @param {string} name Directory name. |
247 * @param {function} successCallback Called on success. | 265 * @param {function} successCallback Called on success. |
248 * @param {function} errorCallback On error. | 266 * @param {function} errorCallback On error. |
249 */ | 267 */ |
250 DirectoryContents.prototype.createDirectory = function( | 268 DirectoryContents.prototype.createDirectory = function( |
251 name, successCallback, errorCallback) { | 269 name, successCallback, errorCallback) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
314 | 332 |
315 /** | 333 /** |
316 * @private | 334 * @private |
317 * @param {Array.<Entry>} entries File list. | 335 * @param {Array.<Entry>} entries File list. |
318 */ | 336 */ |
319 DirectoryContentsBasic.prototype.onChunkComplete_ = function(entries) { | 337 DirectoryContentsBasic.prototype.onChunkComplete_ = function(entries) { |
320 if (this.scanCancelled_) | 338 if (this.scanCancelled_) |
321 return; | 339 return; |
322 | 340 |
323 if (entries.length == 0) { | 341 if (entries.length == 0) { |
324 this.onCompleted(); | 342 this.lastChunkReceived(); |
325 this.recordMetrics_(); | 343 this.recordMetrics_(); |
326 return; | 344 return; |
327 } | 345 } |
328 | 346 |
329 this.onNewEntries(entries); | 347 this.onNewEntries(entries); |
330 }; | 348 }; |
331 | 349 |
332 /** | 350 /** |
333 * @private | 351 * @private |
334 */ | 352 */ |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
429 | 447 |
430 /** | 448 /** |
431 * All the results are read in one chunk, so when we try to read second chunk, | 449 * All the results are read in one chunk, so when we try to read second chunk, |
432 * it means we're done. | 450 * it means we're done. |
433 */ | 451 */ |
434 DirectoryContentsGDataSearch.prototype.readNextChunk = function() { | 452 DirectoryContentsGDataSearch.prototype.readNextChunk = function() { |
435 if (this.scanCancelled_) | 453 if (this.scanCancelled_) |
436 return; | 454 return; |
437 | 455 |
438 if (this.done_) { | 456 if (this.done_) { |
439 this.onCompleted(); | 457 this.lastChunkReceived(); |
dgozman
2012/08/13 12:58:08
May this call fire event for the second time?
Oleg Eterevsky
2012/08/13 13:32:22
It shouldn't. readNextChunk() is called from onPre
| |
440 return; | 458 return; |
441 } | 459 } |
442 | 460 |
443 var searchCallback = (function(entries, nextFeed) { | 461 var searchCallback = (function(entries, nextFeed) { |
444 // TODO(tbarzic): Improve error handling. | 462 // TODO(tbarzic): Improve error handling. |
445 if (!entries) { | 463 if (!entries) { |
446 console.log('Drive search encountered an error'); | 464 console.log('Drive search encountered an error'); |
447 this.onCompleted(); | 465 this.lastChunkReceived(); |
448 return; | 466 return; |
449 } | 467 } |
450 this.nextFeed_ = nextFeed; | 468 this.nextFeed_ = nextFeed; |
451 this.fetchedResultsNum_ += entries.length; | 469 this.fetchedResultsNum_ += entries.length; |
452 if (this.fetchedResultsNum_ >= DirectoryContentsGDataSearch.MAX_RESULTS) | 470 if (this.fetchedResultsNum_ >= DirectoryContentsGDataSearch.MAX_RESULTS) |
453 this.nextFeed_ = ''; | 471 this.nextFeed_ = ''; |
454 | 472 |
455 this.done_ = (this.nextFeed_ == ''); | 473 this.done_ = (this.nextFeed_ == ''); |
456 this.onNewEntries(entries); | 474 this.onNewEntries(entries); |
457 }).bind(this); | 475 }).bind(this); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
531 /** | 549 /** |
532 * Scan a directory. | 550 * Scan a directory. |
533 * @param {DirectoryEntry} entry A directory to scan. | 551 * @param {DirectoryEntry} entry A directory to scan. |
534 * @private | 552 * @private |
535 */ | 553 */ |
536 DirectoryContentsLocalSearch.prototype.scanDirectory_ = function(entry) { | 554 DirectoryContentsLocalSearch.prototype.scanDirectory_ = function(entry) { |
537 this.pendingScans_++; | 555 this.pendingScans_++; |
538 var reader = entry.createReader(); | 556 var reader = entry.createReader(); |
539 var found = []; | 557 var found = []; |
540 | 558 |
541 var self = this; | |
542 | |
543 var onChunkComplete = function(entries) { | 559 var onChunkComplete = function(entries) { |
544 if (self.scanCancelled_) | 560 if (this.scanCancelled_) |
545 return; | 561 return; |
546 | 562 |
547 if (entries.length === 0) { | 563 if (entries.length === 0) { |
548 if (found.length > 0) | 564 if (found.length > 0) |
549 self.onNewEntries(found); | 565 this.onNewEntries(found); |
550 self.pendingScans_--; | 566 this.pendingScans_--; |
551 | 567 if (this.pendingScans_ === 0) |
552 if (self.pendingScans_ === 0) | 568 this.lastChunkReceived(); |
553 self.onCompleted(); | |
554 | |
555 return; | 569 return; |
556 } | 570 } |
557 | 571 |
558 for (var i = 0; i < entries.length; i++) { | 572 for (var i = 0; i < entries.length; i++) { |
559 if (entries[i].name.toLowerCase().indexOf(self.query_) != -1) { | 573 if (entries[i].name.toLowerCase().indexOf(this.query_) != -1) { |
560 found.push(entries[i]); | 574 found.push(entries[i]); |
561 } | 575 } |
562 | 576 |
563 if (entries[i].isDirectory) | 577 if (entries[i].isDirectory) |
564 self.scanDirectory_(entries[i]); | 578 this.scanDirectory_(entries[i]); |
565 } | 579 } |
566 | 580 |
567 getNextChunk(); | 581 getNextChunk(); |
568 }; | 582 }.bind(this); |
569 | 583 |
570 var getNextChunk = function() { | 584 var getNextChunk = function() { |
571 reader.readEntries(onChunkComplete, self.onError.bind(self)); | 585 reader.readEntries(onChunkComplete, this.onError.bind(this)); |
572 }; | 586 }.bind(this); |
573 | 587 |
574 getNextChunk(); | 588 getNextChunk(); |
575 }; | 589 }; |
576 | 590 |
577 /** | 591 /** |
578 * We get results for each directory in one go in scanDirectory_. | 592 * We get results for each directory in one go in scanDirectory_. |
579 */ | 593 */ |
580 DirectoryContentsLocalSearch.prototype.readNextChunk = function() { | 594 DirectoryContentsLocalSearch.prototype.readNextChunk = function() { |
581 }; | 595 }; |
OLD | NEW |