| 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 |