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