| Index: chrome/browser/resources/file_manager/js/directory_model.js
|
| diff --git a/chrome/browser/resources/file_manager/js/directory_model.js b/chrome/browser/resources/file_manager/js/directory_model.js
|
| deleted file mode 100644
|
| index 64a3b2c68345138170f4cc0f7ab9f5ebc83d5ada..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/resources/file_manager/js/directory_model.js
|
| +++ /dev/null
|
| @@ -1,1256 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -'use strict';
|
| -
|
| -// If directory files changes too often, don't rescan directory more than once
|
| -// per specified interval
|
| -var SIMULTANEOUS_RESCAN_INTERVAL = 1000;
|
| -// Used for operations that require almost instant rescan.
|
| -var SHORT_RESCAN_INTERVAL = 100;
|
| -
|
| -/**
|
| - * Data model of the file manager.
|
| - *
|
| - * @param {boolean} singleSelection True if only one file could be selected
|
| - * at the time.
|
| - * @param {FileFilter} fileFilter Instance of FileFilter.
|
| - * @param {FileWatcher} fileWatcher Instance of FileWatcher.
|
| - * @param {MetadataCache} metadataCache The metadata cache service.
|
| - * @param {VolumeManagerWrapper} volumeManager The volume manager.
|
| - * @param {boolean} showSpecialSearchRoots True if special-search roots are
|
| - * available. They should be hidden for the dialogs to save files.
|
| - * @constructor
|
| - */
|
| -function DirectoryModel(singleSelection, fileFilter, fileWatcher,
|
| - metadataCache, volumeManager,
|
| - showSpecialSearchRoots) {
|
| - this.fileListSelection_ = singleSelection ?
|
| - new cr.ui.ListSingleSelectionModel() : new cr.ui.ListSelectionModel();
|
| -
|
| - this.runningScan_ = null;
|
| - this.pendingScan_ = null;
|
| - this.rescanTime_ = null;
|
| - this.scanFailures_ = 0;
|
| - this.showSpecialSearchRoots_ = showSpecialSearchRoots;
|
| -
|
| - this.fileFilter_ = fileFilter;
|
| - this.fileFilter_.addEventListener('changed',
|
| - this.onFilterChanged_.bind(this));
|
| -
|
| - this.currentFileListContext_ = new FileListContext(
|
| - fileFilter, metadataCache);
|
| - this.currentDirContents_ =
|
| - DirectoryContents.createForDirectory(this.currentFileListContext_, null);
|
| -
|
| - this.volumeManager_ = volumeManager;
|
| - this.volumeManager_.volumeInfoList.addEventListener(
|
| - 'splice', this.onVolumeInfoListUpdated_.bind(this));
|
| -
|
| - this.fileWatcher_ = fileWatcher;
|
| - this.fileWatcher_.addEventListener(
|
| - 'watcher-directory-changed',
|
| - this.onWatcherDirectoryChanged_.bind(this));
|
| -}
|
| -
|
| -/**
|
| - * Fake entry to be used in currentDirEntry_ when current directory is
|
| - * unmounted DRIVE. TODO(haruki): Support "drive/root" and "drive/other".
|
| - * @type {Object}
|
| - * @const
|
| - * @private
|
| - */
|
| -DirectoryModel.fakeDriveEntry_ = {
|
| - fullPath: RootDirectory.DRIVE + '/' + DriveSubRootDirectory.ROOT,
|
| - isDirectory: true
|
| -};
|
| -
|
| -/**
|
| - * Fake entry representing a psuedo directory, which contains Drive files
|
| - * available offline. This entry works as a trigger to start a search for
|
| - * offline files.
|
| - * @type {Object}
|
| - * @const
|
| - * @private
|
| - */
|
| -DirectoryModel.fakeDriveOfflineEntry_ = {
|
| - fullPath: RootDirectory.DRIVE_OFFLINE,
|
| - isDirectory: true
|
| -};
|
| -
|
| -/**
|
| - * Fake entry representing a pseudo directory, which contains shared-with-me
|
| - * Drive files. This entry works as a trigger to start a search for
|
| - * shared-with-me files.
|
| - * @type {Object}
|
| - * @const
|
| - * @private
|
| - */
|
| -DirectoryModel.fakeDriveSharedWithMeEntry_ = {
|
| - fullPath: RootDirectory.DRIVE_SHARED_WITH_ME,
|
| - isDirectory: true
|
| -};
|
| -
|
| -/**
|
| - * Fake entry representing a pseudo directory, which contains Drive files
|
| - * accessed recently. This entry works as a trigger to start a metadata search
|
| - * implemented as DirectoryContentsDriveRecent.
|
| - * DirectoryModel is responsible to start the search when the UI tries to open
|
| - * this fake entry (e.g. changeDirectory()).
|
| - * @type {Object}
|
| - * @const
|
| - * @private
|
| - */
|
| -DirectoryModel.fakeDriveRecentEntry_ = {
|
| - fullPath: RootDirectory.DRIVE_RECENT,
|
| - isDirectory: true
|
| -};
|
| -
|
| -/**
|
| - * List of fake entries for special searches.
|
| - *
|
| - * @type {Array.<Object>}
|
| - * @const
|
| - */
|
| -DirectoryModel.FAKE_DRIVE_SPECIAL_SEARCH_ENTRIES = [
|
| - DirectoryModel.fakeDriveSharedWithMeEntry_,
|
| - DirectoryModel.fakeDriveRecentEntry_,
|
| - DirectoryModel.fakeDriveOfflineEntry_
|
| -];
|
| -
|
| -/**
|
| - * DirectoryModel extends cr.EventTarget.
|
| - */
|
| -DirectoryModel.prototype.__proto__ = cr.EventTarget.prototype;
|
| -
|
| -/**
|
| - * Disposes the directory model by removing file watchers.
|
| - */
|
| -DirectoryModel.prototype.dispose = function() {
|
| - this.fileWatcher_.dispose();
|
| -};
|
| -
|
| -/**
|
| - * @return {cr.ui.ArrayDataModel} Files in the current directory.
|
| - */
|
| -DirectoryModel.prototype.getFileList = function() {
|
| - return this.currentFileListContext_.fileList;
|
| -};
|
| -
|
| -/**
|
| - * Sort the file list.
|
| - * @param {string} sortField Sort field.
|
| - * @param {string} sortDirection "asc" or "desc".
|
| - */
|
| -DirectoryModel.prototype.sortFileList = function(sortField, sortDirection) {
|
| - this.getFileList().sort(sortField, sortDirection);
|
| -};
|
| -
|
| -/**
|
| - * @return {cr.ui.ListSelectionModel|cr.ui.ListSingleSelectionModel} Selection
|
| - * in the fileList.
|
| - */
|
| -DirectoryModel.prototype.getFileListSelection = function() {
|
| - return this.fileListSelection_;
|
| -};
|
| -
|
| -/**
|
| - * @return {RootType} Root type of current root.
|
| - */
|
| -DirectoryModel.prototype.getCurrentRootType = function() {
|
| - var entry = this.currentDirContents_.getDirectoryEntry();
|
| - return PathUtil.getRootType(entry ? entry.fullPath : '');
|
| -};
|
| -
|
| -/**
|
| - * @return {string} Root path.
|
| - */
|
| -DirectoryModel.prototype.getCurrentRootPath = function() {
|
| - var entry = this.currentDirContents_.getDirectoryEntry();
|
| - return entry ? PathUtil.getRootPath(entry.fullPath) : '';
|
| -};
|
| -
|
| -/**
|
| - * @return {string} Filesystem URL representing the mountpoint for the current
|
| - * contents.
|
| - */
|
| -DirectoryModel.prototype.getCurrentMountPointUrl = function() {
|
| - var rootPath = this.getCurrentRootPath();
|
| - // Special search roots are just showing a search results from DRIVE.
|
| - if (PathUtil.getRootType(rootPath) == RootType.DRIVE ||
|
| - PathUtil.isSpecialSearchRoot(rootPath))
|
| - return util.makeFilesystemUrl(RootDirectory.DRIVE);
|
| -
|
| - return util.makeFilesystemUrl(rootPath);
|
| -};
|
| -
|
| -/**
|
| - * @return {boolean} on True if offline.
|
| - */
|
| -DirectoryModel.prototype.isDriveOffline = function() {
|
| - var connection = this.volumeManager_.getDriveConnectionState();
|
| - return connection.type == util.DriveConnectionType.OFFLINE;
|
| -};
|
| -
|
| -/**
|
| - * TODO(haruki): This actually checks the current root. Fix the method name and
|
| - * related code.
|
| - * @return {boolean} True if the root for the current directory is read only.
|
| - */
|
| -DirectoryModel.prototype.isReadOnly = function() {
|
| - return this.isPathReadOnly(this.getCurrentRootPath());
|
| -};
|
| -
|
| -/**
|
| - * @return {boolean} True if the a scan is active.
|
| - */
|
| -DirectoryModel.prototype.isScanning = function() {
|
| - return this.currentDirContents_.isScanning();
|
| -};
|
| -
|
| -/**
|
| - * @return {boolean} True if search is in progress.
|
| - */
|
| -DirectoryModel.prototype.isSearching = function() {
|
| - return this.currentDirContents_.isSearch();
|
| -};
|
| -
|
| -/**
|
| - * @param {string} path Path to check.
|
| - * @return {boolean} True if the |path| is read only.
|
| - */
|
| -DirectoryModel.prototype.isPathReadOnly = function(path) {
|
| - // TODO(hidehiko): Migrate this into VolumeInfo.
|
| - switch (PathUtil.getRootType(path)) {
|
| - case RootType.REMOVABLE:
|
| - var volumeInfo = this.volumeManager_.getVolumeInfo(
|
| - PathUtil.getRootPath(path));
|
| - // Returns true if the volume is actually read only, or if an error
|
| - // is found during the mounting.
|
| - // TODO(hidehiko): Remove "error" check here, by removing error'ed volume
|
| - // info from VolumeManager.
|
| - return volumeInfo && (volumeInfo.isReadOnly || !!volumeInfo.error);
|
| - case RootType.ARCHIVE:
|
| - return true;
|
| - case RootType.DOWNLOADS:
|
| - return false;
|
| - case RootType.DRIVE:
|
| - // TODO(haruki): Maybe add DRIVE_OFFLINE as well to allow renaming in the
|
| - // offline tab.
|
| - return this.isDriveOffline();
|
| - default:
|
| - return true;
|
| - }
|
| -};
|
| -
|
| -/**
|
| - * Updates the selection by using the updateFunc and publish the change event.
|
| - * If updateFunc returns true, it force to dispatch the change event even if the
|
| - * selection index is not changed.
|
| - *
|
| - * @param {cr.ui.ListSelectionModel|cr.ui.ListSingleSelectionModel} selection
|
| - * Selection to be updated.
|
| - * @param {function(): boolean} updateFunc Function updating the selection.
|
| - * @private
|
| - */
|
| -DirectoryModel.prototype.updateSelectionAndPublishEvent_ =
|
| - function(selection, updateFunc) {
|
| - // Begin change.
|
| - selection.beginChange();
|
| -
|
| - // If dispatchNeeded is true, we should ensure the change event is
|
| - // dispatched.
|
| - var dispatchNeeded = updateFunc();
|
| -
|
| - // Check if the change event is dispatched in the endChange function
|
| - // or not.
|
| - var eventDispatched = function() { dispatchNeeded = false; };
|
| - selection.addEventListener('change', eventDispatched);
|
| - selection.endChange();
|
| - selection.removeEventListener('change', eventDispatched);
|
| -
|
| - // If the change event have been already dispatched, dispatchNeeded is false.
|
| - if (dispatchNeeded) {
|
| - var event = new Event('change');
|
| - // The selection status (selected or not) is not changed because
|
| - // this event is caused by the change of selected item.
|
| - event.changes = [];
|
| - selection.dispatchEvent(event);
|
| - }
|
| -};
|
| -
|
| -/**
|
| - * Invoked when a change in the directory is detected by the watcher.
|
| - * @private
|
| - */
|
| -DirectoryModel.prototype.onWatcherDirectoryChanged_ = function() {
|
| - this.rescanSoon();
|
| -};
|
| -
|
| -/**
|
| - * Invoked when filters are changed.
|
| - * @private
|
| - */
|
| -DirectoryModel.prototype.onFilterChanged_ = function() {
|
| - this.rescanSoon();
|
| -};
|
| -
|
| -/**
|
| - * Returns the filter.
|
| - * @return {FileFilter} The file filter.
|
| - */
|
| -DirectoryModel.prototype.getFileFilter = function() {
|
| - return this.fileFilter_;
|
| -};
|
| -
|
| -/**
|
| - * @return {DirectoryEntry} Current directory.
|
| - */
|
| -DirectoryModel.prototype.getCurrentDirEntry = function() {
|
| - return this.currentDirContents_.getDirectoryEntry();
|
| -};
|
| -
|
| -/**
|
| - * @return {string} URL of the current directory. or null if unavailable.
|
| - */
|
| -DirectoryModel.prototype.getCurrentDirectoryURL = function() {
|
| - var entry = this.currentDirContents_.getDirectoryEntry();
|
| - if (!entry)
|
| - return null;
|
| - if (entry === DirectoryModel.fakeDriveOfflineEntry_)
|
| - return util.makeFilesystemUrl(entry.fullPath);
|
| - return entry.toURL();
|
| -};
|
| -
|
| -/**
|
| - * @return {string} Path for the current directory, or empty string if the
|
| - * current directory is not yet set.
|
| - */
|
| -DirectoryModel.prototype.getCurrentDirPath = function() {
|
| - var entry = this.currentDirContents_.getDirectoryEntry();
|
| - return entry ? entry.fullPath : '';
|
| -};
|
| -
|
| -/**
|
| - * @return {Array.<string>} File paths of selected files.
|
| - * @private
|
| - */
|
| -DirectoryModel.prototype.getSelectedPaths_ = function() {
|
| - var indexes = this.fileListSelection_.selectedIndexes;
|
| - var fileList = this.getFileList();
|
| - if (fileList) {
|
| - return indexes.map(function(i) {
|
| - return fileList.item(i).fullPath;
|
| - });
|
| - }
|
| - return [];
|
| -};
|
| -
|
| -/**
|
| - * @param {Array.<string>} value List of file paths of selected files.
|
| - * @private
|
| - */
|
| -DirectoryModel.prototype.setSelectedPaths_ = function(value) {
|
| - var indexes = [];
|
| - var fileList = this.getFileList();
|
| -
|
| - var safeKey = function(key) {
|
| - // The transformation must:
|
| - // 1. Never generate a reserved name ('__proto__')
|
| - // 2. Keep different keys different.
|
| - return '#' + key;
|
| - };
|
| -
|
| - var hash = {};
|
| -
|
| - for (var i = 0; i < value.length; i++)
|
| - hash[safeKey(value[i])] = 1;
|
| -
|
| - for (var i = 0; i < fileList.length; i++) {
|
| - if (hash.hasOwnProperty(safeKey(fileList.item(i).fullPath)))
|
| - indexes.push(i);
|
| - }
|
| - this.fileListSelection_.selectedIndexes = indexes;
|
| -};
|
| -
|
| -/**
|
| - * @return {string} Lead item file path.
|
| - * @private
|
| - */
|
| -DirectoryModel.prototype.getLeadPath_ = function() {
|
| - var index = this.fileListSelection_.leadIndex;
|
| - return index >= 0 && this.getFileList().item(index).fullPath;
|
| -};
|
| -
|
| -/**
|
| - * @param {string} value The name of new lead index.
|
| - * @private
|
| - */
|
| -DirectoryModel.prototype.setLeadPath_ = function(value) {
|
| - var fileList = this.getFileList();
|
| - for (var i = 0; i < fileList.length; i++) {
|
| - if (fileList.item(i).fullPath === value) {
|
| - this.fileListSelection_.leadIndex = i;
|
| - return;
|
| - }
|
| - }
|
| -};
|
| -
|
| -/**
|
| - * Schedule rescan with short delay.
|
| - */
|
| -DirectoryModel.prototype.rescanSoon = function() {
|
| - this.scheduleRescan(SHORT_RESCAN_INTERVAL);
|
| -};
|
| -
|
| -/**
|
| - * Schedule rescan with delay. Designed to handle directory change
|
| - * notification.
|
| - */
|
| -DirectoryModel.prototype.rescanLater = function() {
|
| - this.scheduleRescan(SIMULTANEOUS_RESCAN_INTERVAL);
|
| -};
|
| -
|
| -/**
|
| - * Schedule rescan with delay. If another rescan has been scheduled does
|
| - * nothing. File operation may cause a few notifications what should cause
|
| - * a single refresh.
|
| - * @param {number} delay Delay in ms after which the rescan will be performed.
|
| - */
|
| -DirectoryModel.prototype.scheduleRescan = function(delay) {
|
| - if (this.rescanTime_) {
|
| - if (this.rescanTime_ <= Date.now() + delay)
|
| - return;
|
| - clearTimeout(this.rescanTimeoutId_);
|
| - }
|
| -
|
| - this.rescanTime_ = Date.now() + delay;
|
| - this.rescanTimeoutId_ = setTimeout(this.rescan.bind(this), delay);
|
| -};
|
| -
|
| -/**
|
| - * Cancel a rescan on timeout if it is scheduled.
|
| - * @private
|
| - */
|
| -DirectoryModel.prototype.clearRescanTimeout_ = function() {
|
| - this.rescanTime_ = null;
|
| - if (this.rescanTimeoutId_) {
|
| - clearTimeout(this.rescanTimeoutId_);
|
| - this.rescanTimeoutId_ = null;
|
| - }
|
| -};
|
| -
|
| -/**
|
| - * Rescan current directory. May be called indirectly through rescanLater or
|
| - * directly in order to reflect user action. Will first cache all the directory
|
| - * contents in an array, then seamlessly substitute the fileList contents,
|
| - * preserving the select element etc.
|
| - *
|
| - * This should be to scan the contents of current directory (or search).
|
| - */
|
| -DirectoryModel.prototype.rescan = function() {
|
| - this.clearRescanTimeout_();
|
| - if (this.runningScan_) {
|
| - this.pendingRescan_ = true;
|
| - return;
|
| - }
|
| -
|
| - var dirContents = this.currentDirContents_.clone();
|
| - dirContents.setFileList([]);
|
| -
|
| - var successCallback = (function() {
|
| - this.replaceDirectoryContents_(dirContents);
|
| - cr.dispatchSimpleEvent(this, 'rescan-completed');
|
| - }).bind(this);
|
| -
|
| - this.scan_(dirContents,
|
| - successCallback, function() {}, function() {}, function() {});
|
| -};
|
| -
|
| -/**
|
| - * Run scan on the current DirectoryContents. The active fileList is cleared and
|
| - * the entries are added directly.
|
| - *
|
| - * This should be used when changing directory or initiating a new search.
|
| - *
|
| - * @param {DirectoryContentes} newDirContents New DirectoryContents instance to
|
| - * replace currentDirContents_.
|
| - * @param {function()=} opt_callback Called on success.
|
| - * @private
|
| - */
|
| -DirectoryModel.prototype.clearAndScan_ = function(newDirContents,
|
| - opt_callback) {
|
| - if (this.currentDirContents_.isScanning())
|
| - this.currentDirContents_.cancelScan();
|
| - this.currentDirContents_ = newDirContents;
|
| - this.clearRescanTimeout_();
|
| -
|
| - if (this.pendingScan_)
|
| - this.pendingScan_ = false;
|
| -
|
| - if (this.runningScan_) {
|
| - if (this.runningScan_.isScanning())
|
| - this.runningScan_.cancelScan();
|
| - this.runningScan_ = null;
|
| - }
|
| -
|
| - var onDone = function() {
|
| - cr.dispatchSimpleEvent(this, 'scan-completed');
|
| - if (opt_callback)
|
| - opt_callback();
|
| - }.bind(this);
|
| -
|
| - var onFailed = function() {
|
| - cr.dispatchSimpleEvent(this, 'scan-failed');
|
| - }.bind(this);
|
| -
|
| - var onUpdated = function() {
|
| - cr.dispatchSimpleEvent(this, 'scan-updated');
|
| - }.bind(this);
|
| -
|
| - var onCancelled = function() {
|
| - cr.dispatchSimpleEvent(this, 'scan-cancelled');
|
| - }.bind(this);
|
| -
|
| - // Clear the table, and start scanning.
|
| - cr.dispatchSimpleEvent(this, 'scan-started');
|
| - var fileList = this.getFileList();
|
| - fileList.splice(0, fileList.length);
|
| - this.scan_(this.currentDirContents_,
|
| - onDone, onFailed, onUpdated, onCancelled);
|
| -};
|
| -
|
| -/**
|
| - * Perform a directory contents scan. Should be called only from rescan() and
|
| - * clearAndScan_().
|
| - *
|
| - * @param {DirectoryContents} dirContents DirectoryContents instance on which
|
| - * the scan will be run.
|
| - * @param {function()} successCallback Callback on success.
|
| - * @param {function()} failureCallback Callback on failure.
|
| - * @param {function()} updatedCallback Callback on update. Only on the last
|
| - * update, {@code successCallback} is called instead of this.
|
| - * @param {function()} cancelledCallback Callback on cancel.
|
| - * @private
|
| - */
|
| -DirectoryModel.prototype.scan_ = function(
|
| - dirContents,
|
| - successCallback, failureCallback, updatedCallback, cancelledCallback) {
|
| - var self = this;
|
| -
|
| - /**
|
| - * Runs pending scan if there is one.
|
| - *
|
| - * @return {boolean} Did pending scan exist.
|
| - */
|
| - var maybeRunPendingRescan = function() {
|
| - if (self.pendingRescan_) {
|
| - self.rescanSoon();
|
| - self.pendingRescan_ = false;
|
| - return true;
|
| - }
|
| - return false;
|
| - };
|
| -
|
| - var onSuccess = function() {
|
| - self.runningScan_ = null;
|
| - successCallback();
|
| - self.scanFailures_ = 0;
|
| - maybeRunPendingRescan();
|
| - };
|
| -
|
| - var onFailure = function() {
|
| - self.runningScan_ = null;
|
| - self.scanFailures_++;
|
| - failureCallback();
|
| -
|
| - if (maybeRunPendingRescan())
|
| - return;
|
| -
|
| - if (self.scanFailures_ <= 1)
|
| - self.rescanLater();
|
| - };
|
| -
|
| - this.runningScan_ = dirContents;
|
| -
|
| - dirContents.addEventListener('scan-completed', onSuccess);
|
| - dirContents.addEventListener('scan-updated', updatedCallback);
|
| - dirContents.addEventListener('scan-failed', onFailure);
|
| - dirContents.addEventListener('scan-cancelled', cancelledCallback);
|
| - dirContents.scan();
|
| -};
|
| -
|
| -/**
|
| - * @param {DirectoryContents} dirContents DirectoryContents instance.
|
| - * @private
|
| - */
|
| -DirectoryModel.prototype.replaceDirectoryContents_ = function(dirContents) {
|
| - cr.dispatchSimpleEvent(this, 'begin-update-files');
|
| - this.updateSelectionAndPublishEvent_(this.fileListSelection_, function() {
|
| - var selectedPaths = this.getSelectedPaths_();
|
| - var selectedIndices = this.fileListSelection_.selectedIndexes;
|
| -
|
| - // Restore leadIndex in case leadName no longer exists.
|
| - var leadIndex = this.fileListSelection_.leadIndex;
|
| - var leadPath = this.getLeadPath_();
|
| -
|
| - this.currentDirContents_ = dirContents;
|
| - dirContents.replaceContextFileList();
|
| -
|
| - this.setSelectedPaths_(selectedPaths);
|
| - this.fileListSelection_.leadIndex = leadIndex;
|
| - this.setLeadPath_(leadPath);
|
| -
|
| - // If nothing is selected after update, then select file next to the
|
| - // latest selection
|
| - var forceChangeEvent = false;
|
| - if (this.fileListSelection_.selectedIndexes.length == 0 &&
|
| - selectedIndices.length != 0) {
|
| - var maxIdx = Math.max.apply(null, selectedIndices);
|
| - this.selectIndex(Math.min(maxIdx - selectedIndices.length + 2,
|
| - this.getFileList().length) - 1);
|
| - forceChangeEvent = true;
|
| - }
|
| - return forceChangeEvent;
|
| - }.bind(this));
|
| -
|
| - cr.dispatchSimpleEvent(this, 'end-update-files');
|
| -};
|
| -
|
| -/**
|
| - * Callback when an entry is changed.
|
| - * @param {util.EntryChangedKind} kind How the entry is changed.
|
| - * @param {Entry} entry The changed entry.
|
| - */
|
| -DirectoryModel.prototype.onEntryChanged = function(kind, entry) {
|
| - // TODO(hidehiko): We should update directory model even the search result
|
| - // is shown.
|
| - var rootType = this.getCurrentRootType();
|
| - if ((rootType === RootType.DRIVE ||
|
| - rootType === RootType.DRIVE_SHARED_WITH_ME ||
|
| - rootType === RootType.DRIVE_RECENT ||
|
| - rootType === RootType.DRIVE_OFFLINE) &&
|
| - this.isSearching())
|
| - return;
|
| -
|
| - if (kind == util.EntryChangedKind.CREATED) {
|
| - entry.getParent(function(parentEntry) {
|
| - if (this.getCurrentDirEntry().fullPath != parentEntry.fullPath) {
|
| - // Do nothing if current directory changed during async operations.
|
| - return;
|
| - }
|
| - this.currentDirContents_.prefetchMetadata([entry], function() {
|
| - if (this.getCurrentDirEntry().fullPath != parentEntry.fullPath) {
|
| - // Do nothing if current directory changed during async operations.
|
| - return;
|
| - }
|
| -
|
| - var index = this.findIndexByEntry_(entry);
|
| - if (index >= 0)
|
| - this.getFileList().splice(index, 1, entry);
|
| - else
|
| - this.getFileList().push(entry);
|
| - }.bind(this));
|
| - }.bind(this));
|
| - } else {
|
| - // This is the delete event.
|
| - var index = this.findIndexByEntry_(entry);
|
| - if (index >= 0)
|
| - this.getFileList().splice(index, 1);
|
| - }
|
| -};
|
| -
|
| -/**
|
| - * @param {Entry} entry The entry to be searched.
|
| - * @return {number} The index in the fileList, or -1 if not found.
|
| - * @private
|
| - */
|
| -DirectoryModel.prototype.findIndexByEntry_ = function(entry) {
|
| - var fileList = this.getFileList();
|
| - for (var i = 0; i < fileList.length; i++) {
|
| - if (util.isSameEntry(fileList.item(i), entry))
|
| - return i;
|
| - }
|
| - return -1;
|
| -};
|
| -
|
| -/**
|
| - * Called when rename is done successfully.
|
| - * Note: conceptually, DirectoryModel should work without this, because entries
|
| - * can be renamed by other systems anytime and Files.app should reflect it
|
| - * correctly.
|
| - * TODO(hidehiko): investigate more background, and remove this if possible.
|
| - *
|
| - * @param {Entry} oldEntry The old entry.
|
| - * @param {Entry} newEntry The new entry.
|
| - * @param {function()} opt_callback Called on completion.
|
| - */
|
| -DirectoryModel.prototype.onRenameEntry = function(
|
| - oldEntry, newEntry, opt_callback) {
|
| - this.currentDirContents_.prefetchMetadata([newEntry], function() {
|
| - // If the current directory is the old entry, then quietly change to the
|
| - // new one.
|
| - if (util.isSameEntry(oldEntry, this.getCurrentDirEntry()))
|
| - this.changeDirectory(newEntry.fullPath);
|
| -
|
| - // Look for the old entry.
|
| - // If the entry doesn't exist in the list, it has been updated from
|
| - // outside (probably by directory rescan).
|
| - var index = this.findIndexByEntry_(oldEntry);
|
| - if (index >= 0) {
|
| - // Update the content list and selection status.
|
| - var wasSelected = this.fileListSelection_.getIndexSelected(index);
|
| - this.updateSelectionAndPublishEvent_(this.fileListSelection_, function() {
|
| - this.fileListSelection_.setIndexSelected(index, false);
|
| - this.getFileList().splice(index, 1, newEntry);
|
| - if (wasSelected) {
|
| - // We re-search the index, because splice may trigger sorting so that
|
| - // index may be stale.
|
| - this.fileListSelection_.setIndexSelected(
|
| - this.findIndexByEntry_(newEntry), true);
|
| - }
|
| - return true;
|
| - }.bind(this));
|
| - }
|
| -
|
| - // Run callback, finally.
|
| - if (opt_callback)
|
| - opt_callback();
|
| - }.bind(this));
|
| -};
|
| -
|
| -/**
|
| - * Creates directory and updates the file list.
|
| - *
|
| - * @param {string} name Directory name.
|
| - * @param {function(DirectoryEntry)} successCallback Callback on success.
|
| - * @param {function(FileError)} errorCallback Callback on failure.
|
| - */
|
| -DirectoryModel.prototype.createDirectory = function(name, successCallback,
|
| - errorCallback) {
|
| - var entry = this.getCurrentDirEntry();
|
| - if (!entry) {
|
| - errorCallback(util.createFileError(FileError.INVALID_MODIFICATION_ERR));
|
| - return;
|
| - }
|
| -
|
| - var onSuccess = function(newEntry) {
|
| - // Do not change anything or call the callback if current
|
| - // directory changed.
|
| - if (entry.fullPath != this.getCurrentDirPath())
|
| - return;
|
| -
|
| - var existing = this.getFileList().slice().filter(
|
| - function(e) {return e.name == name;});
|
| -
|
| - if (existing.length) {
|
| - this.selectEntry(name);
|
| - successCallback(existing[0]);
|
| - } else {
|
| - this.fileListSelection_.beginChange();
|
| - this.getFileList().splice(0, 0, newEntry);
|
| - this.selectEntry(name);
|
| - this.fileListSelection_.endChange();
|
| - successCallback(newEntry);
|
| - }
|
| - };
|
| -
|
| - this.currentDirContents_.createDirectory(name, onSuccess.bind(this),
|
| - errorCallback);
|
| -};
|
| -
|
| -/**
|
| - * Changes directory. Causes 'directory-change' event.
|
| - *
|
| - * @param {string} path New current directory path.
|
| - * @param {function(FileError)=} opt_errorCallback Executed if the change
|
| - * directory failed.
|
| - */
|
| -DirectoryModel.prototype.changeDirectory = function(path, opt_errorCallback) {
|
| - if (PathUtil.isSpecialSearchRoot(path)) {
|
| - this.specialSearch(path, '');
|
| - return;
|
| - }
|
| -
|
| - this.resolveDirectory(path, function(directoryEntry) {
|
| - this.changeDirectoryEntry_(directoryEntry);
|
| - }.bind(this), function(error) {
|
| - console.error('Error changing directory to ' + path + ': ', error);
|
| - if (opt_errorCallback)
|
| - opt_errorCallback(error);
|
| - });
|
| -};
|
| -
|
| -/**
|
| - * Resolves absolute directory path. Handles Drive stub. If the drive is
|
| - * mounting, callbacks will be called after the mount is completed.
|
| - *
|
| - * @param {string} path Path to the directory.
|
| - * @param {function(DirectoryEntry)} successCallback Success callback.
|
| - * @param {function(FileError)} errorCallback Error callback.
|
| - */
|
| -DirectoryModel.prototype.resolveDirectory = function(
|
| - path, successCallback, errorCallback) {
|
| - if (PathUtil.getRootType(path) == RootType.DRIVE) {
|
| - if (!this.volumeManager_.getVolumeInfo(RootDirectory.DRIVE)) {
|
| - errorCallback(util.createFileError(FileError.NOT_FOUND_ERR));
|
| - return;
|
| - }
|
| - }
|
| -
|
| - var onError = function(error) {
|
| - // Handle the special case, when in offline mode, and there are no cached
|
| - // contents on the C++ side. In such case, let's display the stub.
|
| - // The INVALID_STATE_ERR error code is returned from the drive filesystem
|
| - // in such situation.
|
| - //
|
| - // TODO(mtomasz, hashimoto): Consider rewriting this logic.
|
| - // crbug.com/253464.
|
| - if (PathUtil.getRootType(path) == RootType.DRIVE &&
|
| - error.code == FileError.INVALID_STATE_ERR) {
|
| - successCallback(DirectoryModel.fakeDriveEntry_);
|
| - return;
|
| - }
|
| - errorCallback(error);
|
| - }.bind(this);
|
| -
|
| - this.volumeManager_.resolvePath(
|
| - path,
|
| - function(entry) {
|
| - if (entry.isFile) {
|
| - onError(util.createFileError(FileError.TYPE_MISMATCH_ERR));
|
| - return;
|
| - }
|
| - successCallback(entry);
|
| - },
|
| - onError);
|
| -};
|
| -
|
| -/**
|
| - * @param {DirectoryEntry} dirEntry The absolute path to the new directory.
|
| - * @param {function()=} opt_callback Executed if the directory loads
|
| - * successfully.
|
| - * @private
|
| - */
|
| -DirectoryModel.prototype.changeDirectoryEntrySilent_ = function(dirEntry,
|
| - opt_callback) {
|
| - var onScanComplete = function() {
|
| - if (opt_callback)
|
| - opt_callback();
|
| - // For tests that open the dialog to empty directories, everything
|
| - // is loaded at this point.
|
| - chrome.test.sendMessage('directory-change-complete');
|
| - };
|
| - this.clearAndScan_(
|
| - DirectoryContents.createForDirectory(this.currentFileListContext_,
|
| - dirEntry),
|
| - onScanComplete.bind(this));
|
| -};
|
| -
|
| -/**
|
| - * Change the current directory to the directory represented by a
|
| - * DirectoryEntry.
|
| - *
|
| - * Dispatches the 'directory-changed' event when the directory is successfully
|
| - * changed.
|
| - *
|
| - * @param {DirectoryEntry} dirEntry The absolute path to the new directory.
|
| - * @param {function()=} opt_callback Executed if the directory loads
|
| - * successfully.
|
| - * @private
|
| - */
|
| -DirectoryModel.prototype.changeDirectoryEntry_ = function(
|
| - dirEntry, opt_callback) {
|
| - this.fileWatcher_.changeWatchedDirectory(dirEntry, function() {
|
| - var previous = this.currentDirContents_.getDirectoryEntry();
|
| - this.clearSearch_();
|
| - this.changeDirectoryEntrySilent_(dirEntry, opt_callback);
|
| -
|
| - var e = new Event('directory-changed');
|
| - e.previousDirEntry = previous;
|
| - e.newDirEntry = dirEntry;
|
| - this.dispatchEvent(e);
|
| - }.bind(this));
|
| -};
|
| -
|
| -/**
|
| - * Creates an object which could say whether directory has changed while it has
|
| - * been active or not. Designed for long operations that should be cancelled
|
| - * if the used change current directory.
|
| - * @return {Object} Created object.
|
| - */
|
| -DirectoryModel.prototype.createDirectoryChangeTracker = function() {
|
| - var tracker = {
|
| - dm_: this,
|
| - active_: false,
|
| - hasChanged: false,
|
| -
|
| - start: function() {
|
| - if (!this.active_) {
|
| - this.dm_.addEventListener('directory-changed',
|
| - this.onDirectoryChange_);
|
| - this.active_ = true;
|
| - this.hasChanged = false;
|
| - }
|
| - },
|
| -
|
| - stop: function() {
|
| - if (this.active_) {
|
| - this.dm_.removeEventListener('directory-changed',
|
| - this.onDirectoryChange_);
|
| - this.active_ = false;
|
| - }
|
| - },
|
| -
|
| - onDirectoryChange_: function(event) {
|
| - tracker.stop();
|
| - tracker.hasChanged = true;
|
| - }
|
| - };
|
| - return tracker;
|
| -};
|
| -
|
| -/**
|
| - * Change the state of the model to reflect the specified path (either a
|
| - * file or directory).
|
| - * TODO(hidehiko): This logic should be merged with
|
| - * FileManager.setupCurrentDirectory_.
|
| - *
|
| - * @param {string} path The root path to use.
|
| - * @param {function(string, string, boolean)=} opt_pathResolveCallback Invoked
|
| - * as soon as the path has been resolved, and called with the base and leaf
|
| - * portions of the path name, and a flag indicating if the entry exists.
|
| - * Will be called even if another directory change happened while setupPath
|
| - * was in progress, but will pass |false| as |exist| parameter.
|
| - */
|
| -DirectoryModel.prototype.setupPath = function(path, opt_pathResolveCallback) {
|
| - var tracker = this.createDirectoryChangeTracker();
|
| - tracker.start();
|
| -
|
| - var self = this;
|
| - var resolveCallback = function(directoryPath, fileName, exists) {
|
| - tracker.stop();
|
| - if (!opt_pathResolveCallback)
|
| - return;
|
| - opt_pathResolveCallback(directoryPath, fileName,
|
| - exists && !tracker.hasChanged);
|
| - };
|
| -
|
| - var changeDirectoryEntry = function(directoryEntry, opt_callback) {
|
| - tracker.stop();
|
| - if (!tracker.hasChanged)
|
| - self.changeDirectoryEntry_(directoryEntry, opt_callback);
|
| - };
|
| -
|
| - var EXISTS = true;
|
| -
|
| - var changeToDefault = function(leafName) {
|
| - var def = PathUtil.DEFAULT_DIRECTORY;
|
| - self.resolveDirectory(def, function(directoryEntry) {
|
| - resolveCallback(def, leafName, !EXISTS);
|
| - changeDirectoryEntry(directoryEntry);
|
| - }, function(error) {
|
| - console.error('Failed to resolve default directory: ' + def, error);
|
| - resolveCallback('/', leafName, !EXISTS);
|
| - });
|
| - };
|
| -
|
| - var noParentDirectory = function(leafName, error) {
|
| - console.warn('Can\'t resolve parent directory: ' + path, error);
|
| - changeToDefault(leafName);
|
| - };
|
| -
|
| - if (DirectoryModel.isSystemDirectory(path)) {
|
| - changeToDefault('');
|
| - return;
|
| - }
|
| -
|
| - this.resolveDirectory(path, function(directoryEntry) {
|
| - resolveCallback(directoryEntry.fullPath, '', !EXISTS);
|
| - changeDirectoryEntry(directoryEntry);
|
| - }, function(error) {
|
| - // Usually, leaf does not exist, because it's just a suggested file name.
|
| - var fileExists = error.code == FileError.TYPE_MISMATCH_ERR;
|
| - var nameDelimiter = path.lastIndexOf('/');
|
| - var parentDirectoryPath = path.substr(0, nameDelimiter);
|
| - var leafName = path.substr(nameDelimiter + 1);
|
| - if (fileExists || error.code == FileError.NOT_FOUND_ERR) {
|
| - if (DirectoryModel.isSystemDirectory(parentDirectoryPath)) {
|
| - changeToDefault(leafName);
|
| - return;
|
| - }
|
| - self.resolveDirectory(parentDirectoryPath,
|
| - function(parentDirectoryEntry) {
|
| - var fileName = path.substr(nameDelimiter + 1);
|
| - resolveCallback(parentDirectoryEntry.fullPath, fileName, fileExists);
|
| - changeDirectoryEntry(parentDirectoryEntry,
|
| - function() {
|
| - self.selectEntry(fileName);
|
| - });
|
| - }, noParentDirectory.bind(null, leafName));
|
| - } else {
|
| - // Unexpected errors.
|
| - console.error('Directory resolving error: ', error);
|
| - changeToDefault(leafName);
|
| - }
|
| - });
|
| -};
|
| -
|
| -/**
|
| - * @param {string} name Filename.
|
| - */
|
| -DirectoryModel.prototype.selectEntry = function(name) {
|
| - var fileList = this.getFileList();
|
| - for (var i = 0; i < fileList.length; i++) {
|
| - if (fileList.item(i).name == name) {
|
| - this.selectIndex(i);
|
| - return;
|
| - }
|
| - }
|
| -};
|
| -
|
| -/**
|
| - * @param {Array.<string>} urls Array of URLs.
|
| - */
|
| -DirectoryModel.prototype.selectUrls = function(urls) {
|
| - var fileList = this.getFileList();
|
| - this.fileListSelection_.beginChange();
|
| - this.fileListSelection_.unselectAll();
|
| - for (var i = 0; i < fileList.length; i++) {
|
| - if (urls.indexOf(fileList.item(i).toURL()) >= 0)
|
| - this.fileListSelection_.setIndexSelected(i, true);
|
| - }
|
| - this.fileListSelection_.endChange();
|
| -};
|
| -
|
| -/**
|
| - * @param {number} index Index of file.
|
| - */
|
| -DirectoryModel.prototype.selectIndex = function(index) {
|
| - // this.focusCurrentList_();
|
| - if (index >= this.getFileList().length)
|
| - return;
|
| -
|
| - // If a list bound with the model it will do scrollIndexIntoView(index).
|
| - this.fileListSelection_.selectedIndex = index;
|
| -};
|
| -
|
| -/**
|
| - * Called when VolumeInfoList is updated.
|
| - *
|
| - * @param {Event} event Event of VolumeInfoList's 'splice'.
|
| - * @private
|
| - */
|
| -DirectoryModel.prototype.onVolumeInfoListUpdated_ = function(event) {
|
| - var driveVolume = this.volumeManager_.getVolumeInfo(RootDirectory.DRIVE);
|
| - if (driveVolume && !driveVolume.error) {
|
| - var currentDirEntry = this.getCurrentDirEntry();
|
| - if (currentDirEntry) {
|
| - if (currentDirEntry === DirectoryModel.fakeDriveEntry_) {
|
| - // Replace the fake entry by real DirectoryEntry silently.
|
| - this.volumeManager_.resolvePath(
|
| - DirectoryModel.fakeDriveEntry_.fullPath,
|
| - function(entry) {
|
| - // If the current entry is still fake drive entry, replace it.
|
| - if (this.getCurrentDirEntry() === DirectoryModel.fakeDriveEntry_)
|
| - this.changeDirectoryEntrySilent_(entry);
|
| - },
|
| - function(error) {});
|
| - } else if (PathUtil.isSpecialSearchRoot(currentDirEntry.fullPath)) {
|
| - for (var i = 0; i < event.added.length; i++) {
|
| - if (event.added[i].volumeType == util.VolumeType.DRIVE) {
|
| - // If the Drive volume is newly mounted, rescan it.
|
| - this.rescan();
|
| - break;
|
| - }
|
| - }
|
| - }
|
| - }
|
| - }
|
| -
|
| - var rootPath = this.getCurrentRootPath();
|
| - var rootType = PathUtil.getRootType(rootPath);
|
| -
|
| - // If the path is on drive, reduce to the Drive's mount point.
|
| - if (rootType === RootType.DRIVE)
|
| - rootPath = RootDirectory.DRIVE;
|
| -
|
| - // When the volume where we are is unmounted, fallback to
|
| - // DEFAULT_DIRECTORY.
|
| - // Note: during the initialization, rootType can be undefined.
|
| - if (rootType && !this.volumeManager_.getVolumeInfo(rootPath))
|
| - this.changeDirectory(PathUtil.DEFAULT_DIRECTORY);
|
| -};
|
| -
|
| -/**
|
| - * @param {string} path Path.
|
| - * @return {boolean} If current directory is system.
|
| - */
|
| -DirectoryModel.isSystemDirectory = function(path) {
|
| - path = path.replace(/\/+$/, '');
|
| - return path === RootDirectory.REMOVABLE || path === RootDirectory.ARCHIVE;
|
| -};
|
| -
|
| -/**
|
| - * Check if the root of the given path is mountable or not.
|
| - *
|
| - * @param {string} path Path.
|
| - * @return {boolean} Return true, if the given path is under mountable root.
|
| - * Otherwise, return false.
|
| - */
|
| -DirectoryModel.isMountableRoot = function(path) {
|
| - var rootType = PathUtil.getRootType(path);
|
| - switch (rootType) {
|
| - case RootType.DOWNLOADS:
|
| - return false;
|
| - case RootType.ARCHIVE:
|
| - case RootType.REMOVABLE:
|
| - case RootType.DRIVE:
|
| - return true;
|
| - default:
|
| - throw new Error('Unknown root type!');
|
| - }
|
| -};
|
| -
|
| -/**
|
| - * Performs search and displays results. The search type is dependent on the
|
| - * current directory. If we are currently on drive, server side content search
|
| - * over drive mount point. If the current directory is not on the drive, file
|
| - * name search over current directory will be performed.
|
| - *
|
| - * @param {string} query Query that will be searched for.
|
| - * @param {function(Event)} onSearchRescan Function that will be called when the
|
| - * search directory is rescanned (i.e. search results are displayed).
|
| - * @param {function()} onClearSearch Function to be called when search state
|
| - * gets cleared.
|
| - * TODO(olege): Change callbacks to events.
|
| - */
|
| -DirectoryModel.prototype.search = function(query,
|
| - onSearchRescan,
|
| - onClearSearch) {
|
| - query = query.trimLeft();
|
| -
|
| - this.clearSearch_();
|
| -
|
| - var currentDirEntry = this.getCurrentDirEntry();
|
| - if (!currentDirEntry) {
|
| - // Not yet initialized. Do nothing.
|
| - return;
|
| - }
|
| -
|
| - if (!query) {
|
| - if (this.isSearching()) {
|
| - var newDirContents = DirectoryContents.createForDirectory(
|
| - this.currentFileListContext_,
|
| - this.currentDirContents_.getLastNonSearchDirectoryEntry());
|
| - this.clearAndScan_(newDirContents);
|
| - }
|
| - return;
|
| - }
|
| -
|
| - this.onSearchCompleted_ = onSearchRescan;
|
| - this.onClearSearch_ = onClearSearch;
|
| -
|
| - this.addEventListener('scan-completed', this.onSearchCompleted_);
|
| -
|
| - // If we are offline, let's fallback to file name search inside dir.
|
| - // A search initiated from directories in Drive or special search results
|
| - // should trigger Drive search.
|
| - var newDirContents;
|
| - if (!this.isDriveOffline() &&
|
| - PathUtil.isDriveBasedPath(currentDirEntry.fullPath)) {
|
| - // Drive search is performed over the whole drive, so pass drive root as
|
| - // |directoryEntry|.
|
| - newDirContents = DirectoryContents.createForDriveSearch(
|
| - this.currentFileListContext_,
|
| - currentDirEntry,
|
| - this.currentDirContents_.getLastNonSearchDirectoryEntry(),
|
| - query);
|
| - } else {
|
| - newDirContents = DirectoryContents.createForLocalSearch(
|
| - this.currentFileListContext_, currentDirEntry, query);
|
| - }
|
| - this.clearAndScan_(newDirContents);
|
| -};
|
| -
|
| -/**
|
| - * Performs special search and displays results. e.g. Drive files available
|
| - * offline, shared-with-me files, recently modified files.
|
| - * @param {string} path Path string representing special search. See fake
|
| - * entries in PathUtil.RootDirectory.
|
| - * @param {string=} opt_query Query string used for the search.
|
| - */
|
| -DirectoryModel.prototype.specialSearch = function(path, opt_query) {
|
| - var query = opt_query || '';
|
| -
|
| - this.clearSearch_();
|
| -
|
| - this.onSearchCompleted_ = null;
|
| - this.onClearSearch_ = null;
|
| -
|
| - var onDriveDirectoryResolved = function(driveRoot) {
|
| - if (!driveRoot || driveRoot == DirectoryModel.fakeDriveEntry_) {
|
| - // Drive root not available or not ready. onVolumeInfoListUpdated_()
|
| - // handles the rescan if necessary.
|
| - driveRoot = null;
|
| - }
|
| -
|
| - var specialSearchType = PathUtil.getRootType(path);
|
| - var searchOption;
|
| - var dirEntry;
|
| - if (specialSearchType == RootType.DRIVE_OFFLINE) {
|
| - dirEntry = DirectoryModel.fakeDriveOfflineEntry_;
|
| - searchOption =
|
| - DriveMetadataSearchContentScanner.SearchType.SEARCH_OFFLINE;
|
| - } else if (specialSearchType == RootType.DRIVE_SHARED_WITH_ME) {
|
| - dirEntry = DirectoryModel.fakeDriveSharedWithMeEntry_;
|
| - searchOption =
|
| - DriveMetadataSearchContentScanner.SearchType.SEARCH_SHARED_WITH_ME;
|
| - } else if (specialSearchType == RootType.DRIVE_RECENT) {
|
| - dirEntry = DirectoryModel.fakeDriveRecentEntry_;
|
| - searchOption =
|
| - DriveMetadataSearchContentScanner.SearchType.SEARCH_RECENT_FILES;
|
| -
|
| - } else {
|
| - // Unknown path.
|
| - this.changeDirectory(PathUtil.DEFAULT_DIRECTORY);
|
| - return;
|
| - }
|
| -
|
| - var newDirContents = DirectoryContents.createForDriveMetadataSearch(
|
| - this.currentFileListContext_,
|
| - dirEntry, driveRoot, query, searchOption);
|
| - var previous = this.currentDirContents_.getDirectoryEntry();
|
| - this.clearAndScan_(newDirContents);
|
| -
|
| - var e = new Event('directory-changed');
|
| - e.previousDirEntry = previous;
|
| - e.newDirEntry = dirEntry;
|
| - this.dispatchEvent(e);
|
| - }.bind(this);
|
| -
|
| - this.resolveDirectory(DirectoryModel.fakeDriveEntry_.fullPath,
|
| - onDriveDirectoryResolved /* success */,
|
| - function() {} /* failed */);
|
| -};
|
| -
|
| -/**
|
| - * In case the search was active, remove listeners and send notifications on
|
| - * its canceling.
|
| - * @private
|
| - */
|
| -DirectoryModel.prototype.clearSearch_ = function() {
|
| - if (!this.isSearching())
|
| - return;
|
| -
|
| - if (this.onSearchCompleted_) {
|
| - this.removeEventListener('scan-completed', this.onSearchCompleted_);
|
| - this.onSearchCompleted_ = null;
|
| - }
|
| -
|
| - if (this.onClearSearch_) {
|
| - this.onClearSearch_();
|
| - this.onClearSearch_ = null;
|
| - }
|
| -};
|
|
|