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 'use strict'; | 5 'use strict'; |
6 | 6 |
7 /** | 7 /** |
8 * Scanner of the entries. | 8 * Scanner of the entries. |
9 * @constructor | 9 * @constructor |
10 */ | 10 */ |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
453 this.fileList_ = context.fileList; | 453 this.fileList_ = context.fileList; |
454 | 454 |
455 this.isSearch_ = isSearch; | 455 this.isSearch_ = isSearch; |
456 this.directoryEntry_ = directoryEntry; | 456 this.directoryEntry_ = directoryEntry; |
457 this.lastNonSearchDirectoryEntry_ = lastNonSearchDirectoryEntry; | 457 this.lastNonSearchDirectoryEntry_ = lastNonSearchDirectoryEntry; |
458 | 458 |
459 this.scannerFactory_ = scannerFactory; | 459 this.scannerFactory_ = scannerFactory; |
460 this.scanner_ = null; | 460 this.scanner_ = null; |
461 this.prefetchMetadataQueue_ = new AsyncUtil.Queue(); | 461 this.prefetchMetadataQueue_ = new AsyncUtil.Queue(); |
462 this.scanCancelled_ = false; | 462 this.scanCancelled_ = false; |
463 this.fileList_.prepareSort = this.prepareSort_.bind(this); | |
464 } | 463 } |
465 | 464 |
466 /** | 465 /** |
467 * DirectoryContents extends cr.EventTarget. | 466 * DirectoryContents extends cr.EventTarget. |
468 */ | 467 */ |
469 DirectoryContents.prototype.__proto__ = cr.EventTarget.prototype; | 468 DirectoryContents.prototype.__proto__ = cr.EventTarget.prototype; |
470 | 469 |
471 /** | 470 /** |
472 * Create the copy of the object, but without scan started. | 471 * Create the copy of the object, but without scan started. |
473 * @return {DirectoryContents} Object copy. | 472 * @return {DirectoryContents} Object copy. |
474 */ | 473 */ |
475 DirectoryContents.prototype.clone = function() { | 474 DirectoryContents.prototype.clone = function() { |
476 return new DirectoryContents( | 475 return new DirectoryContents( |
477 this.context_, this.isSearch_, this.directoryEntry_, | 476 this.context_, this.isSearch_, this.directoryEntry_, |
478 this.lastNonSearchDirectoryEntry_, this.scannerFactory_); | 477 this.lastNonSearchDirectoryEntry_, this.scannerFactory_); |
479 }; | 478 }; |
480 | 479 |
481 /** | 480 /** |
482 * Use a given fileList instead of the fileList from the context. | 481 * Use a given fileList instead of the fileList from the context. |
483 * @param {Array|cr.ui.ArrayDataModel} fileList The new file list. | 482 * @param {Array|cr.ui.ArrayDataModel} fileList The new file list. |
484 */ | 483 */ |
485 DirectoryContents.prototype.setFileList = function(fileList) { | 484 DirectoryContents.prototype.setFileList = function(fileList) { |
486 this.fileList_ = fileList; | 485 if (fileList instanceof cr.ui.ArrayDataModel) |
487 this.fileList_.prepareSort = this.prepareSort_.bind(this); | 486 this.fileList_ = fileList; |
| 487 else |
| 488 this.fileList_ = new cr.ui.ArrayDataModel(fileList); |
| 489 this.context_.metadataCache.setCacheSize(this.fileList_.length); |
488 }; | 490 }; |
489 | 491 |
490 /** | 492 /** |
491 * Use the filelist from the context and replace its contents with the entries | 493 * Use the filelist from the context and replace its contents with the entries |
492 * from the current fileList. | 494 * from the current fileList. |
493 */ | 495 */ |
494 DirectoryContents.prototype.replaceContextFileList = function() { | 496 DirectoryContents.prototype.replaceContextFileList = function() { |
495 if (this.context_.fileList !== this.fileList_) { | 497 if (this.context_.fileList !== this.fileList_) { |
496 var spliceArgs = [].slice.call(this.fileList_); | 498 var spliceArgs = this.fileList_.slice(); |
497 var fileList = this.context_.fileList; | 499 var fileList = this.context_.fileList; |
498 spliceArgs.unshift(0, fileList.length); | 500 spliceArgs.unshift(0, fileList.length); |
499 fileList.splice.apply(fileList, spliceArgs); | 501 fileList.splice.apply(fileList, spliceArgs); |
500 this.fileList_ = fileList; | 502 this.fileList_ = fileList; |
| 503 this.context_.metadataCache.setCacheSize(this.fileList_.length); |
501 } | 504 } |
502 }; | 505 }; |
503 | 506 |
504 /** | 507 /** |
505 * @return {boolean} If the scan is active. | 508 * @return {boolean} If the scan is active. |
506 */ | 509 */ |
507 DirectoryContents.prototype.isScanning = function() { | 510 DirectoryContents.prototype.isScanning = function() { |
508 return this.scanner_ || this.prefetchMetadataQueue_.isRunning(); | 511 return this.scanner_ || this.prefetchMetadataQueue_.isRunning(); |
509 }; | 512 }; |
510 | 513 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
598 if (this.scanCancelled_) | 601 if (this.scanCancelled_) |
599 return; | 602 return; |
600 | 603 |
601 var entriesFiltered = [].filter.call( | 604 var entriesFiltered = [].filter.call( |
602 entries, this.context_.fileFilter.filter.bind(this.context_.fileFilter)); | 605 entries, this.context_.fileFilter.filter.bind(this.context_.fileFilter)); |
603 | 606 |
604 // Update the filelist without waiting the metadata. | 607 // Update the filelist without waiting the metadata. |
605 this.fileList_.push.apply(this.fileList_, entriesFiltered); | 608 this.fileList_.push.apply(this.fileList_, entriesFiltered); |
606 cr.dispatchSimpleEvent(this, 'scan-updated'); | 609 cr.dispatchSimpleEvent(this, 'scan-updated'); |
607 | 610 |
| 611 this.context_.metadataCache.setCacheSize(this.fileList_.length); |
| 612 |
608 // Because the prefetchMetadata can be slow, throttling by splitting entries | 613 // Because the prefetchMetadata can be slow, throttling by splitting entries |
609 // into smaller chunks to reduce UI latency. | 614 // into smaller chunks to reduce UI latency. |
610 // TODO(hidehiko,mtomasz): This should be handled in MetadataCache. | 615 // TODO(hidehiko,mtomasz): This should be handled in MetadataCache. |
611 var MAX_CHUNK_SIZE = 50; | 616 var MAX_CHUNK_SIZE = 50; |
612 for (var i = 0; i < entriesFiltered.length; i += MAX_CHUNK_SIZE) { | 617 for (var i = 0; i < entriesFiltered.length; i += MAX_CHUNK_SIZE) { |
613 var chunk = entriesFiltered.slice(i, i + MAX_CHUNK_SIZE); | 618 var chunk = entriesFiltered.slice(i, i + MAX_CHUNK_SIZE); |
614 this.prefetchMetadataQueue_.run(function(chunk, callback) { | 619 this.prefetchMetadataQueue_.run(function(chunk, callback) { |
615 this.prefetchMetadata(chunk, function() { | 620 this.prefetchMetadata(chunk, function() { |
616 if (this.scanCancelled_) { | 621 if (this.scanCancelled_) { |
617 // Do nothing if the scanning is cancelled. | 622 // Do nothing if the scanning is cancelled. |
618 callback(); | 623 callback(); |
619 return; | 624 return; |
620 } | 625 } |
621 | 626 |
| 627 // TODO(yoshiki): Here we should fire the update event of changed |
| 628 // items. Currently we have a method this.fileList_.updateIndex() to |
| 629 // fire an event, but this method takes only 1 argument and invokes sort |
| 630 // one by one. It is obviously time wasting. Instead, we call sort |
| 631 // directory. |
| 632 // In future, we should implement a good method like updateIndexes and |
| 633 // use it here. |
| 634 var status = this.fileList_.sortStatus; |
| 635 this.fileList_.sort(status.field, status.direction); |
| 636 |
622 cr.dispatchSimpleEvent(this, 'scan-updated'); | 637 cr.dispatchSimpleEvent(this, 'scan-updated'); |
623 callback(); | 638 callback(); |
624 }.bind(this)); | 639 }.bind(this)); |
625 }.bind(this, chunk)); | 640 }.bind(this, chunk)); |
626 } | 641 } |
627 }; | 642 }; |
628 | 643 |
629 /** | 644 /** |
630 * Cache necessary data before a sort happens. | |
631 * | |
632 * This is called by the table code before a sort happens, so that we can | |
633 * go fetch data for the sort field that we may not have yet. | |
634 * @param {string} field Sort field. | |
635 * @param {function(Object)} callback Called when done. | |
636 * @private | |
637 */ | |
638 DirectoryContents.prototype.prepareSort_ = function(field, callback) { | |
639 this.prefetchMetadata(this.fileList_.slice(), callback); | |
640 }; | |
641 | |
642 /** | |
643 * @param {Array.<Entry>} entries Files. | 645 * @param {Array.<Entry>} entries Files. |
644 * @param {function(Object)} callback Callback on done. | 646 * @param {function(Object)} callback Callback on done. |
645 */ | 647 */ |
646 DirectoryContents.prototype.prefetchMetadata = function(entries, callback) { | 648 DirectoryContents.prototype.prefetchMetadata = function(entries, callback) { |
647 this.context_.metadataCache.get(entries, 'filesystem', callback); | 649 this.context_.metadataCache.get(entries, 'filesystem', callback); |
648 }; | 650 }; |
649 | 651 |
650 /** | 652 /** |
651 * @param {Array.<Entry>} entries Files. | 653 * @param {Array.<Entry>} entries Files. |
652 * @param {function(Object)} callback Callback on done. | 654 * @param {function(Object)} callback Callback on done. |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 context, fakeDirectoryEntry, driveDirectoryEntry, query, searchType) { | 763 context, fakeDirectoryEntry, driveDirectoryEntry, query, searchType) { |
762 return new DirectoryContents( | 764 return new DirectoryContents( |
763 context, | 765 context, |
764 true, // Search | 766 true, // Search |
765 fakeDirectoryEntry, | 767 fakeDirectoryEntry, |
766 driveDirectoryEntry, | 768 driveDirectoryEntry, |
767 function() { | 769 function() { |
768 return new DriveMetadataSearchContentScanner(query, searchType); | 770 return new DriveMetadataSearchContentScanner(query, searchType); |
769 }); | 771 }); |
770 }; | 772 }; |
OLD | NEW |