directory_contents.js revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)'use strict'; 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Scanner of the entries. 94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @constructor 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)function ContentScanner() { 124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) this.cancelled_ = false; 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/** 164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Starts to scan the entries. For example, starts to read the entries in a 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * directory, or starts to search with some query on a file system. 184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Derived classes must override this method. 194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * 204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @param {function(Array.<Entry>)} entriesCallback Called when some chunk of 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * entries are read. This can be called a couple of times until the 224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * completion. 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @param {function()} successCallback Called when the scan is completed 244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * successfully. 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @param {function(FileError)} errorCallback Called an error occurs. 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ContentScanner.prototype.scan = function( 284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) entriesCallback, successCallback, errorCallback) { 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/** 324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Request cancelling of the running scan. When the cancelling is done, 334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * an error will be reported from errorCallback passed to scan(). 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ContentScanner.prototype.cancel = function() { 364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) this.cancelled_ = true; 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/** 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Scanner of the entries in a directory. 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @param {DirectoryEntry} entry The directory to be read. 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @constructor 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @extends {ContentScanner} 444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)function DirectoryContentScanner(entry) { 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ContentScanner.call(this); 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) this.entry_ = entry; 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/** 514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Extends ContentScanner. 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)DirectoryContentScanner.prototype.__proto__ = ContentScanner.prototype; 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/** 564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Starts to read the entries in the directory. 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @override 584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)DirectoryContentScanner.prototype.scan = function( 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) entriesCallback, successCallback, errorCallback) { 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!this.entry_ || util.isFakeEntry(this.entry_)) { 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // If entry is not specified or a fake, we cannot read it. 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errorCallback(util.createDOMError( 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) util.FileError.INVALID_MODIFICATION_ERR)); 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) metrics.startInterval('DirectoryScan'); 694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) var reader = this.entry_.createReader(); 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) var readEntries = function() { 714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) reader.readEntries( 724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) function(entries) { 734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (this.cancelled_) { 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errorCallback(util.createDOMError(util.FileError.ABORT_ERR)); 754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (entries.length === 0) { 794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // All entries are read. 804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) metrics.recordInterval('DirectoryScan'); 814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) successCallback(); 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) entriesCallback(entries); 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) readEntries(); 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }.bind(this), 884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errorCallback); 894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }.bind(this); 904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) readEntries(); 914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/** 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Scanner of the entries for the search results on Drive File System. 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @param {string} query The query string. 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @constructor 974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @extends {ContentScanner} 984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)function DriveSearchContentScanner(query) { 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ContentScanner.call(this); 1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) this.query_ = query; 1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/** 1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Extends ContentScanner. 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)DriveSearchContentScanner.prototype.__proto__ = ContentScanner.prototype; 1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/** 1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Delay in milliseconds to be used for drive search scan, in order to reduce 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * the number of server requests while user is typing the query. 1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @type {number} 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @private 1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @const 1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)DriveSearchContentScanner.SCAN_DELAY_ = 200; 1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/** 1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Maximum number of results which is shown on the search. 1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @type {number} 1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @private 1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @const 1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)DriveSearchContentScanner.MAX_RESULTS_ = 100; 1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/** 1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Starts to search on Drive File System. 1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @override 1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)DriveSearchContentScanner.prototype.scan = function( 1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) entriesCallback, successCallback, errorCallback) { 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) var numReadEntries = 0; 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) var readEntries = function(nextFeed) { 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) chrome.fileBrowserPrivate.searchDrive( 1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) {query: this.query_, nextFeed: nextFeed}, 1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) function(entries, nextFeed) { 1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (this.cancelled_) { 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errorCallback(util.createDOMError(util.FileError.ABORT_ERR)); 1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // TODO(tbarzic): Improve error handling. 1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!entries) { 1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) console.error('Drive search encountered an error.'); 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errorCallback(util.createDOMError( 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) util.FileError.INVALID_MODIFICATION_ERR)); 1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) var numRemainingEntries = 1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DriveSearchContentScanner.MAX_RESULTS_ - numReadEntries; 1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (entries.length >= numRemainingEntries) { 1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // The limit is hit, so quit the scan here. 1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) entries = entries.slice(0, numRemainingEntries); 1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) nextFeed = ''; 1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) numReadEntries += entries.length; 1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (entries.length > 0) 1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) entriesCallback(entries); 1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (nextFeed === '') 1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) successCallback(); 1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) else 1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) readEntries(nextFeed); 1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }.bind(this)); 1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }.bind(this); 1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Let's give another search a chance to cancel us before we begin. 1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) setTimeout( 1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) function() { 1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Check cancelled state before read the entries. 1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (this.cancelled_) { 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errorCallback(util.createDOMError(util.FileError.ABORT_ERR)); 1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) readEntries(''); 1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }.bind(this), 1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DriveSearchContentScanner.SCAN_DELAY_); 1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/** 1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Scanner of the entries of the file name search on the directory tree, whose 1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * root is entry. 1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @param {DirectoryEntry} entry The root of the search target directory tree. 1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @param {string} query The query of the search. 1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @constructor 1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @extends {ContentScanner} 1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)function LocalSearchContentScanner(entry, query) { 1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ContentScanner.call(this); 1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) this.entry_ = entry; 1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) this.query_ = query.toLowerCase(); 1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/** 197c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * Extends ContentScanner. 1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)LocalSearchContentScanner.prototype.__proto__ = ContentScanner.prototype; 2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/** 2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Starts the file name search. 2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @override 2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)LocalSearchContentScanner.prototype.scan = function( 2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) entriesCallback, successCallback, errorCallback) { 2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) var numRunningTasks = 0; 2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) var error = null; 2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) var maybeRunCallback = function() { 2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (numRunningTasks === 0) { 2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (this.cancelled_) 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errorCallback(util.createDOMError(util.FileError.ABORT_ERR)); 2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) else if (error) 2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errorCallback(error); 2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) else 2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) successCallback(); 2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }.bind(this); 2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) var processEntry = function(entry) { 2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) numRunningTasks++; 2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) var onError = function(fileError) { 2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!error) 2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = fileError; 2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) numRunningTasks--; 2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) maybeRunCallback(); 2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }; 2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) var onSuccess = function(entries) { 2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (this.cancelled_ || error || entries.length === 0) { 2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) numRunningTasks--; 2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) maybeRunCallback(); 2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Filters by the query, and if found, run entriesCallback. 2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) var foundEntries = entries.filter(function(entry) { 2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return entry.name.toLowerCase().indexOf(this.query_) >= 0; 2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }.bind(this)); 2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (foundEntries.length > 0) 2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) entriesCallback(foundEntries); 2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Start to process sub directories. 2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (var i = 0; i < entries.length; i++) { 2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (entries[i].isDirectory) 2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) processEntry(entries[i]); 2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Read remaining entries. 2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) reader.readEntries(onSuccess, onError); 2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }.bind(this); 2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) var reader = entry.createReader(); 2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) reader.readEntries(onSuccess, onError); 2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }.bind(this); 2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) processEntry(this.entry_); 2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/** 2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Scanner of the entries for the metadata search on Drive File System. 2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @param {DriveMetadataSearchContentScanner.SearchType} searchType The option 2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * of the search. 2644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @constructor 2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @extends {ContentScanner} 2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)function DriveMetadataSearchContentScanner(searchType) { 2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ContentScanner.call(this); 2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) this.searchType_ = searchType; 2704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/** 2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Extends ContentScanner. 2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)DriveMetadataSearchContentScanner.prototype.__proto__ = 2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ContentScanner.prototype; 2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/** 2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * The search types on the Drive File System. 2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @enum {string} 2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)DriveMetadataSearchContentScanner.SearchType = Object.freeze({ 2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SEARCH_ALL: 'ALL', 2844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SEARCH_SHARED_WITH_ME: 'SHARED_WITH_ME', 2854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SEARCH_RECENT_FILES: 'EXCLUDE_DIRECTORIES', 2864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SEARCH_OFFLINE: 'OFFLINE' 2874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}); 2884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/** 2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Starts to metadata-search on Drive File System. 2914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @override 2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 2934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)DriveMetadataSearchContentScanner.prototype.scan = function( 2944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) entriesCallback, successCallback, errorCallback) { 2954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) chrome.fileBrowserPrivate.searchDriveMetadata( 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) {query: '', types: this.searchType_, maxResults: 500}, 2974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) function(results) { 2984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (this.cancelled_) { 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errorCallback(util.createDOMError(util.FileError.ABORT_ERR)); 3004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 3014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!results) { 3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) console.error('Drive search encountered an error.'); 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errorCallback(util.createDOMError( 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) util.FileError.INVALID_MODIFICATION_ERR)); 3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) var entries = results.map(function(result) { return result.entry; }); 3114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (entries.length > 0) 3124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) entriesCallback(entries); 3134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) successCallback(); 3144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }.bind(this)); 3154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 3164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/** 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * This class manages filters and determines a file should be shown or not. 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * When filters are changed, a 'changed' event is fired. 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {MetadataCache} metadataCache Metadata cache service. 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {boolean} showHidden If files starting with '.' are shown. 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @constructor 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * @extends {cr.EventTarget} 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)function FileFilter(metadataCache, showHidden) { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {MetadataCache} 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * @private 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this.metadataCache_ = metadataCache; 3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type Object.<string, Function> 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.filters_ = {}; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.setFilterHidden(!showHidden); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do not show entries marked as 'deleted'. 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.addFilter('deleted', function(entry) { 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) var internal = this.metadataCache_.getCached(entry, 'internal'); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !(internal && internal.deleted); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }.bind(this)); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/* 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * FileFilter extends cr.EventTarget. 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */ 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)FileFilter.prototype = {__proto__: cr.EventTarget.prototype}; 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} name Filter identifier. 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {function(Entry)} callback A filter — a function receiving an Entry, 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and returning bool. 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)FileFilter.prototype.addFilter = function(name, callback) { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.filters_[name] = callback; 359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cr.dispatchSimpleEvent(this, 'changed'); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} name Filter identifier. 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)FileFilter.prototype.removeFilter = function(name) { 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete this.filters_[name]; 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cr.dispatchSimpleEvent(this, 'changed'); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {boolean} value If do not show hidden files. 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)FileFilter.prototype.setFilterHidden = function(value) { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value) { 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.addFilter( 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'hidden', 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) function(entry) { return entry.name.substr(0, 1) !== '.'; } 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.removeFilter('hidden'); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {boolean} If the files with names starting with "." are not shown. 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)FileFilter.prototype.isFilterHiddenOn = function() { 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 'hidden' in this.filters_; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Entry} entry File entry. 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {boolean} True if the file should be shown, false otherwise. 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)FileFilter.prototype.filter = function(entry) { 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (var name in this.filters_) { 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!this.filters_[name](entry)) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/** 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * A context of DirectoryContents. 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * TODO(yoshiki): remove this. crbug.com/224869. 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * @param {FileFilter} fileFilter The file-filter context. 408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * @param {MetadataCache} metadataCache Metadata cache service. 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * @constructor 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */ 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)function FileListContext(fileFilter, metadataCache) { 412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /** 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * @type {cr.ui.ArrayDataModel} 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */ 415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) this.fileList = new cr.ui.ArrayDataModel([]); 4164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /** 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * @type {MetadataCache} 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */ 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this.metadataCache = metadataCache; 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /** 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * @type {FileFilter} 424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */ 425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this.fileFilter = fileFilter; 426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This class is responsible for scanning directory (or search results), 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and filling the fileList. Different descendants handle various types of 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * directory contents shown: basic directory, drive search results, local search 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * results. 4334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * TODO(hidehiko): Remove EventTarget from this. 4344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {FileListContext} context The file list context. 4364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @param {boolean} isSearch True for search directory contents, otherwise 4374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * false. 4384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @param {DirectoryEntry} directoryEntry The entry of the current directory. 4394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @param {function():ContentScanner} scannerFactory The factory to create 4404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * ContentScanner instance. 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @constructor 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @extends {cr.EventTarget} 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)function DirectoryContents(context, 4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) isSearch, 4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) directoryEntry, 4474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scannerFactory) { 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.context_ = context; 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.fileList_ = context.fileList; 4504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) this.isSearch_ = isSearch; 4524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) this.directoryEntry_ = directoryEntry; 4534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) this.scannerFactory_ = scannerFactory; 4554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) this.scanner_ = null; 456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.processNewEntriesQueue_ = new AsyncUtil.Queue(); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.scanCancelled_ = false; 458f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 459f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) this.lastSpaceInMetadataCache_ = 0; 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * DirectoryContents extends cr.EventTarget. 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DirectoryContents.prototype.__proto__ = cr.EventTarget.prototype; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create the copy of the object, but without scan started. 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {DirectoryContents} Object copy. 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DirectoryContents.prototype.clone = function() { 4724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return new DirectoryContents( 4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this.context_, 4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this.isSearch_, 4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this.directoryEntry_, 4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this.scannerFactory_); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 480f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) * Disposes the reserved metadata cache. 481f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) */ 482f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)DirectoryContents.prototype.dispose = function() { 483f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) this.context_.metadataCache.resizeBy(-this.lastSpaceInMetadataCache_); 484f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}; 485f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 486f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)/** 487f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) * Make a space for current directory size in the metadata cache. 488f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) * 489f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) * @param {number} size The cache size to be set. 490f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) * @private 491f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) */ 492f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)DirectoryContents.prototype.makeSpaceInMetadataCache_ = function(size) { 493f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) this.context_.metadataCache.resizeBy(size - this.lastSpaceInMetadataCache_); 494f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) this.lastSpaceInMetadataCache_ = size; 495f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}; 496f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 497f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)/** 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Use a given fileList instead of the fileList from the context. 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Array|cr.ui.ArrayDataModel} fileList The new file list. 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DirectoryContents.prototype.setFileList = function(fileList) { 5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (fileList instanceof cr.ui.ArrayDataModel) 5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this.fileList_ = fileList; 5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this.fileList_ = new cr.ui.ArrayDataModel(fileList); 506f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) this.makeSpaceInMetadataCache_(this.fileList_.length); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Use the filelist from the context and replace its contents with the entries 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * from the current fileList. 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DirectoryContents.prototype.replaceContextFileList = function() { 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this.context_.fileList !== this.fileList_) { 5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var spliceArgs = this.fileList_.slice(); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var fileList = this.context_.fileList; 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spliceArgs.unshift(0, fileList.length); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fileList.splice.apply(fileList, spliceArgs); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.fileList_ = fileList; 520f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) this.makeSpaceInMetadataCache_(this.fileList_.length); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {boolean} If the scan is active. 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DirectoryContents.prototype.isScanning = function() { 528cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return this.scanner_ || this.processNewEntriesQueue_.isRunning(); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {boolean} True if search results (drive or local). 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DirectoryContents.prototype.isSearch = function() { 5354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return this.isSearch_; 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {DirectoryEntry} A DirectoryEntry for current directory. In case of 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * search -- the top directory from which search is run. 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DirectoryContents.prototype.getDirectoryEntry = function() { 5434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return this.directoryEntry_; 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Start directory scan/search operation. Either 'scan-completed' or 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 'scan-failed' event will be fired upon completion. 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DirectoryContents.prototype.scan = function() { 551effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch /** 552effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch * Invoked when the scanning is completed successfully. 553effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch * @this {DirectoryContents} 554effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch */ 555effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch function completionCallback() { 556effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch this.onScanFinished_(); 557effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch this.onScanCompleted_(); 558effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 559effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 560effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch /** 561effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch * Invoked when the scanning is finished but is not completed due to error. 562effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch * @this {DirectoryContents} 563effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch */ 564effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch function errorCallback() { 565effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch this.onScanFinished_(); 566effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch this.onScanError_(); 567effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 568effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 5694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // TODO(hidehiko,mtomasz): this scan method must be called at most once. 5704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Remove such a limitation. 5714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) this.scanner_ = this.scannerFactory_(); 5724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) this.scanner_.scan(this.onNewEntries_.bind(this), 573effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch completionCallback.bind(this), 574effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch errorCallback.bind(this)); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 5784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Cancels the running scan. 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DirectoryContents.prototype.cancelScan = function() { 581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (this.scanCancelled_) 582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.scanCancelled_ = true; 5844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (this.scanner_) 5854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) this.scanner_.cancel(); 5864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 587effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch this.onScanFinished_(); 588effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 589cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.processNewEntriesQueue_.cancel(); 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cr.dispatchSimpleEvent(this, 'scan-cancelled'); 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/** 594effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch * Called when the scanning by scanner_ is done, even when the scanning is 595effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch * succeeded or failed. This is called before completion (or error) callback. 596effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch * 5974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @private 5984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 599effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochDirectoryContents.prototype.onScanFinished_ = function() { 6004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) this.scanner_ = null; 601effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 602cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.processNewEntriesQueue_.run(function(callback) { 603effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // TODO(yoshiki): Here we should fire the update event of changed 604effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // items. Currently we have a method this.fileList_.updateIndex() to 605effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // fire an event, but this method takes only 1 argument and invokes sort 606effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // one by one. It is obviously time wasting. Instead, we call sort 607effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // directory. 608effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // In future, we should implement a good method like updateIndexes and 609effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // use it here. 610effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch var status = this.fileList_.sortStatus; 611effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (status) 612effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch this.fileList_.sort(status.field, status.direction); 613effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 614effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch callback(); 615effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch }.bind(this)); 616effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}; 617effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 618effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch/** 619effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch * Called when the scanning by scanner_ is succeeded. 620effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch * @private 621effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch */ 622effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochDirectoryContents.prototype.onScanCompleted_ = function() { 6234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (this.scanCancelled_) 6244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 6254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 626cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.processNewEntriesQueue_.run(function(callback) { 6274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Call callback first, so isScanning() returns false in the event handlers. 6284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) callback(); 629effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 6304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) cr.dispatchSimpleEvent(this, 'scan-completed'); 6314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }.bind(this)); 6324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called in case scan has failed. Should send the event. 6364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @private 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)DirectoryContents.prototype.onScanError_ = function() { 6394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (this.scanCancelled_) 6404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 6414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 642cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.processNewEntriesQueue_.run(function(callback) { 6434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Call callback first, so isScanning() returns false in the event handlers. 6444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) callback(); 6454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) cr.dispatchSimpleEvent(this, 'scan-failed'); 6464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }.bind(this)); 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 6504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Called when some chunk of entries are read by scanner. 6514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @param {Array.<Entry>} entries The list of the scanned entries. 6524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @private 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)DirectoryContents.prototype.onNewEntries_ = function(entries) { 6554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (this.scanCancelled_) 6564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 6574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) var entriesFiltered = [].filter.call( 6594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) entries, this.context_.fileFilter.filter.bind(this.context_.fileFilter)); 6604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 661010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Caching URL to reduce a number of calls of toURL in sort. 662010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // This is a temporary solution. We need to fix a root cause of slow toURL. 663010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // See crbug.com/370908 for detail. 664010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) entriesFiltered.forEach(function(entry) { entry.cachedUrl = entry.toURL(); }); 665010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 66646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (entriesFiltered.length === 0) 66746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 66846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 669f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Enlarge the cache size into the new filelist size. 670f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) var newListSize = this.fileList_.length + entriesFiltered.length; 671f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) this.makeSpaceInMetadataCache_(newListSize); 6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 673cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.processNewEntriesQueue_.run(function(callbackOuter) { 674f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) var finish = function() { 675f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Update the filelist without waiting the metadata. 676f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) this.fileList_.push.apply(this.fileList_, entriesFiltered); 677f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) cr.dispatchSimpleEvent(this, 'scan-updated'); 678f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 679f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) callbackOuter(); 680f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) }.bind(this); 681cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Because the prefetchMetadata can be slow, throttling by splitting entries 682cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // into smaller chunks to reduce UI latency. 683cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(hidehiko,mtomasz): This should be handled in MetadataCache. 684cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var MAX_CHUNK_SIZE = 25; 685cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var prefetchMetadataQueue = new AsyncUtil.ConcurrentQueue(4); 686cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (var i = 0; i < entriesFiltered.length; i += MAX_CHUNK_SIZE) { 687cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (prefetchMetadataQueue.isCancelled()) 688cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 689cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 690cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var chunk = entriesFiltered.slice(i, i + MAX_CHUNK_SIZE); 691cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) prefetchMetadataQueue.run(function(chunk, callbackInner) { 692cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.prefetchMetadata(chunk, function() { 693cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!prefetchMetadataQueue.isCancelled()) { 694cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (this.scanCancelled_) 695cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) prefetchMetadataQueue.cancel(); 696cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 6974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 698cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Checks if this is the last task. 699cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (prefetchMetadataQueue.getWaitingTasksCount() === 0 && 700cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) prefetchMetadataQueue.getRunningTasksCount() === 1) { 701f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // |callbackOuter| in |finish| must be called before 702f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // |callbackInner|, to prevent double-calling. 703f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) finish(); 704cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 705cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 706cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callbackInner(); 707cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }.bind(this)); 708cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }.bind(this, chunk)); 709cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 710cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }.bind(this)); 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Array.<Entry>} entries Files. 715558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * @param {function(Object)} callback Callback on done. 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DirectoryContents.prototype.prefetchMetadata = function(entries, callback) { 718f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) this.context_.metadataCache.getLatest(entries, 'filesystem|drive', callback); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 7224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Creates a DirectoryContents instance to show entries in a directory. 723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 7244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @param {FileListContext} context File list context. 7254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @param {DirectoryEntry} directoryEntry The current directory entry. 7264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @return {DirectoryContents} Created DirectoryContents instance. 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)DirectoryContents.createForDirectory = function(context, directoryEntry) { 7294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return new DirectoryContents( 7304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) context, 7314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) false, // Non search. 7324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) directoryEntry, 7334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) function() { 7344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return new DirectoryContentScanner(directoryEntry); 7354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }); 7364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 7394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Creates a DirectoryContents instance to show the result of the search on 7404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Drive File System. 741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {FileListContext} context File list context. 7434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @param {DirectoryEntry} directoryEntry The current directory entry. 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} query Search query. 7454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @return {DirectoryContents} Created DirectoryContents instance. 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)DirectoryContents.createForDriveSearch = function( 7485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) context, directoryEntry, query) { 7494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return new DirectoryContents( 7504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) context, 7514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) true, // Search. 7524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) directoryEntry, 7534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) function() { 7544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return new DriveSearchContentScanner(query); 7554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }); 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 7594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Creates a DirectoryContents instance to show the result of the search on 7604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Local File System. 7614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {FileListContext} context File list context. 7634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @param {DirectoryEntry} directoryEntry The current directory entry. 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} query Search query. 7654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @return {DirectoryContents} Created DirectoryContents instance. 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)DirectoryContents.createForLocalSearch = function( 7684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) context, directoryEntry, query) { 7694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return new DirectoryContents( 7704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) context, 7714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) true, // Search. 7724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) directoryEntry, 7734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) function() { 7744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return new LocalSearchContentScanner(directoryEntry, query); 7754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }); 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 7794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Creates a DirectoryContents instance to show the result of metadata search 7804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * on Drive File System. 781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * @param {FileListContext} context File list context. 7834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @param {DirectoryEntry} fakeDirectoryEntry Fake directory entry representing 7844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * the set of result entries. This serves as a top directory for the 7854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * search. 7864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @param {DriveMetadataSearchContentScanner.SearchType} searchType The type of 7874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * the search. The scanner will restricts the entries based on the given 7884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * type. 7894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @return {DirectoryContents} Created DirectoryContents instance. 7904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 7914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)DirectoryContents.createForDriveMetadataSearch = function( 7925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) context, fakeDirectoryEntry, searchType) { 7934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return new DirectoryContents( 7944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) context, 7954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) true, // Search 7964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) fakeDirectoryEntry, 7974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) function() { 7985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return new DriveMetadataSearchContentScanner(searchType); 7994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }); 800c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 801