| Index: chrome/browser/resources/file_manager/js/file_manager.js
|
| diff --git a/chrome/browser/resources/file_manager/js/file_manager.js b/chrome/browser/resources/file_manager/js/file_manager.js
|
| index a9f05c4e33e6e982c4489c79f9b1e11133a5b6d9..df39eef9b0cb21096bd47047c55f12db2c42ef68 100644
|
| --- a/chrome/browser/resources/file_manager/js/file_manager.js
|
| +++ b/chrome/browser/resources/file_manager/js/file_manager.js
|
| @@ -208,10 +208,10 @@ FileManager.prototype = {
|
| var localStrings;
|
|
|
| /**
|
| - * Map of icon types to regular expressions.
|
| + * Map of icon types to regular expressions and functions
|
| *
|
| - * The first regexp to match the file name determines the icon type
|
| - * assigned to dom elements for a file. Order of evaluation is not
|
| + * The first regexp/function to match the entry name determines the icon type
|
| + * assigned to dom elements for a file. Order of evaluation is not
|
| * defined, so don't depend on it.
|
| */
|
| const iconTypes = {
|
| @@ -220,13 +220,33 @@ FileManager.prototype = {
|
| 'image': /\.(bmp|gif|jpe?g|ico|png|webp)$/i,
|
| 'pdf' : /\.(pdf)$/i,
|
| 'text': /\.(pod|rst|txt|log)$/i,
|
| - 'video': /\.(3gp|avi|mov|mp4|m4v|mpe?g4?|ogm|ogv|ogx|webm)$/i
|
| + 'video': /\.(3gp|avi|mov|mp4|m4v|mpe?g4?|ogm|ogv|ogx|webm)$/i,
|
| + 'device': function(self, entry) {
|
| + var deviceNumber = self.getDeviceNumber(entry);
|
| + if (deviceNumber != undefined)
|
| + return (self.mountPoints_[deviceNumber].mountCondition == '');
|
| + return false;
|
| + },
|
| + 'unreadable': function(self, entry) {
|
| + var deviceNumber = self.getDeviceNumber(entry);
|
| + if (deviceNumber != undefined) {
|
| + return self.mountPoints_[deviceNumber].mountCondition ==
|
| + 'unknown_filesystem' ||
|
| + self.mountPoints_[deviceNumber].mountCondition ==
|
| + 'unsupported_filesystem';
|
| + }
|
| + return false;
|
| + }
|
| };
|
|
|
| const previewArt = {
|
| 'audio': 'images/filetype_large_audio.png',
|
| + // TODO(sidor): Find better icon here.
|
| + 'device': 'images/filetype_large_folder.png',
|
| 'folder': 'images/filetype_large_folder.png',
|
| 'unknown': 'images/filetype_large_generic.png',
|
| + // TODO(sidor): Find better icon here.
|
| + 'unreadable': 'images/filetype_large_folder.png',
|
| 'video': 'images/filetype_large_video.png'
|
| };
|
|
|
| @@ -294,50 +314,19 @@ FileManager.prototype = {
|
| return parent;
|
| }
|
|
|
| - /**
|
| - * Get the icon type for a given Entry.
|
| - *
|
| - * @param {Entry} entry An Entry subclass (FileEntry or DirectoryEntry).
|
| - * @return {string} One of the keys from FileManager.iconTypes, or
|
| - * 'unknown'.
|
| - */
|
| - function getIconType(entry) {
|
| - if (entry.cachedIconType_)
|
| - return entry.cachedIconType_;
|
| -
|
| - var rv = 'unknown';
|
| -
|
| - if (entry.isDirectory) {
|
| - rv = 'folder';
|
| - } else {
|
| - for (var name in iconTypes) {
|
| - var value = iconTypes[name];
|
| -
|
| - if (value instanceof RegExp) {
|
| - if (value.test(entry.name)) {
|
| - rv = name;
|
| - break;
|
| - }
|
| - } else if (typeof value == 'function') {
|
| - try {
|
| - if (value(entry)) {
|
| - rv = name;
|
| - break;
|
| - }
|
| - } catch (ex) {
|
| - console.error('Caught exception while evaluating iconType: ' +
|
| - name, ex);
|
| - }
|
| - } else {
|
| - console.log('Unexpected value in iconTypes[' + name + ']: ' + value);
|
| - }
|
| - }
|
| - }
|
| -
|
| - entry.cachedIconType_ = rv;
|
| - return rv;
|
| + /**
|
| + * Normalizes path not to start with /
|
| + *
|
| + * @param {string} path The file path.
|
| + */
|
| + function normalizeAbsolutePath(x) {
|
| + if (x[0] == '/')
|
| + return x.slice(1);
|
| + else
|
| + return x;
|
| }
|
|
|
| +
|
| /**
|
| * Call an asynchronous method on dirEntry, batching multiple callers.
|
| *
|
| @@ -479,27 +468,6 @@ FileManager.prototype = {
|
| }
|
| }
|
|
|
| - /**
|
| - * Get the icon type of a file, caching the result.
|
| - *
|
| - * When this method completes, the fileEntry object will get a
|
| - * 'cachedIconType_' property (if it doesn't already have one) containing the
|
| - * icon type of the file as a string.
|
| - *
|
| - * The successCallback is always invoked synchronously, since this does not
|
| - * actually require an async call. You should not depend on this, as it may
|
| - * change if we were to start reading magic numbers (for example).
|
| - *
|
| - * @param {Entry} entry An HTML5 Entry object.
|
| - * @param {function(Entry)} successCallback The function to invoke once the
|
| - * icon type is known.
|
| - */
|
| - function cacheEntryIconType(entry, successCallback) {
|
| - getIconType(entry);
|
| - if (successCallback)
|
| - setTimeout(function() { successCallback(entry) }, 0);
|
| - }
|
| -
|
| function isSystemDirEntry(dirEntry) {
|
| return dirEntry.fullPath == '/' ||
|
| dirEntry.fullPath == REMOVABLE_DIRECTORY ||
|
| @@ -659,6 +627,68 @@ FileManager.prototype = {
|
| };
|
|
|
| /**
|
| + * Get the icon type for a given Entry.
|
| + *
|
| + * @param {Entry} entry An Entry subclass (FileEntry or DirectoryEntry).
|
| + * @return {string} One of the keys from FileManager.iconTypes, or
|
| + * 'unknown'.
|
| + */
|
| + FileManager.prototype.getIconType = function(entry) {
|
| + if (entry.cachedIconType_)
|
| + return entry.cachedIconType_;
|
| +
|
| + var rv = 'unknown';
|
| + if (entry.isDirectory)
|
| + rv = 'folder';
|
| + for (var name in iconTypes) {
|
| + var value = iconTypes[name];
|
| +
|
| + if (value instanceof RegExp) {
|
| + if (value.test(entry.name)) {
|
| + rv = name;
|
| + break;
|
| + }
|
| + } else if (typeof value == 'function') {
|
| + try {
|
| + if (value(this,entry)) {
|
| + rv = name;
|
| + break;
|
| + }
|
| + } catch (ex) {
|
| + console.error('Caught exception while evaluating iconType: ' +
|
| + name, ex);
|
| + }
|
| + } else {
|
| + console.log('Unexpected value in iconTypes[' + name + ']: ' + value);
|
| + }
|
| + }
|
| + entry.cachedIconType_ = rv;
|
| + return rv;
|
| + };
|
| +
|
| +
|
| + /**
|
| + * Get the icon type of a file, caching the result.
|
| + *
|
| + * When this method completes, the fileEntry object will get a
|
| + * 'cachedIconType_' property (if it doesn't already have one) containing the
|
| + * icon type of the file as a string.
|
| + *
|
| + * The successCallback is always invoked synchronously, since this does not
|
| + * actually require an async call. You should not depend on this, as it may
|
| + * change if we were to start reading magic numbers (for example).
|
| + *
|
| + * @param {Entry} entry An HTML5 Entry object.
|
| + * @param {function(Entry)} successCallback The function to invoke once the
|
| + * icon type is known.
|
| + */
|
| + FileManager.prototype.cacheEntryIconType = function(entry, successCallback) {
|
| + this.getIconType(entry);
|
| + if (successCallback)
|
| + setTimeout(function() { successCallback(entry) }, 0);
|
| + }
|
| +
|
| + /**
|
| * Compare by mtime first, then by name.
|
| */
|
| FileManager.prototype.compareMtime_ = function(a, b) {
|
| @@ -1244,7 +1274,7 @@ FileManager.prototype = {
|
| } else if (field == 'cachedSize_') {
|
| cacheFunction = cacheEntrySize;
|
| } else if (field == 'cachedIconType_') {
|
| - cacheFunction = cacheEntryIconType;
|
| + cacheFunction = this.cacheEntryIconType.bind(this);
|
| } else {
|
| callback();
|
| return;
|
| @@ -1351,7 +1381,7 @@ FileManager.prototype = {
|
|
|
| var icon = this.document_.createElement('div');
|
| icon.className = 'detail-icon';
|
| - entry.cachedIconType_ = getIconType(entry);
|
| + entry.cachedIconType_ = this.getIconType(entry);
|
| icon.setAttribute('iconType', entry.cachedIconType_);
|
| div.appendChild(icon);
|
|
|
| @@ -1486,9 +1516,9 @@ FileManager.prototype = {
|
| selection.urls.push(entry.toURL());
|
|
|
| if (selection.iconType == null) {
|
| - selection.iconType = getIconType(entry);
|
| + selection.iconType = this.getIconType(entry);
|
| } else if (selection.iconType != 'unknown') {
|
| - var iconType = getIconType(entry);
|
| + var iconType = this.getIconType(entry);
|
| if (selection.iconType != iconType)
|
| selection.iconType = 'unknown';
|
| }
|
| @@ -1719,19 +1749,11 @@ FileManager.prototype = {
|
| var self = this;
|
| function onMountPointsFound(mountPoints) {
|
| self.mountPoints_ = mountPoints;
|
| -
|
| - function normalize(x) {
|
| - if (x[0] == '/')
|
| - return x.slice(1);
|
| - else
|
| - return x;
|
| - }
|
| -
|
| function onVolumeMetadataFound(volumeMetadata) {
|
| if (volumeMetadata.deviceType == "flash") {
|
| - if (selection.entries.length != 1 ||
|
| - normalize(selection.entries[0].fullPath) !=
|
| - normalize(volumeMetadata.mountPath)) {
|
| + if (self.selection.entries.length != 1 ||
|
| + normalizeAbsolutePath(self.selection.entries[0].fullPath) !=
|
| + normalizeAbsolutePath(volumeMetadata.mountPath)) {
|
| return;
|
| }
|
| var task = {
|
| @@ -1748,7 +1770,8 @@ FileManager.prototype = {
|
| var selectedPath = selection.entries[0].fullPath;
|
| for (var i = 0; i < mountPoints.length; i++) {
|
| if (mountPoints[i].mountType == "device" &&
|
| - normalize(mountPoints[i].mountPath) == normalize(selectedPath)) {
|
| + normalizeAbsolutePath(mountPoints[i].mountPath) ==
|
| + normalizeAbsolutePath(selectedPath)) {
|
| chrome.fileBrowserPrivate.getVolumeMetadata(mountPoints[i].sourceUrl,
|
| onVolumeMetadataFound);
|
| return;
|
| @@ -1802,11 +1825,16 @@ FileManager.prototype = {
|
| return;
|
| }
|
|
|
| + var rescanDirectoryNeeded = (event.status == 'success');
|
| + for (var i = 0; i < mountPoints.length; i++) {
|
| + if (event.sourceUrl == mountPoints[i].sourceUrl &&
|
| + mountPoints[i].mountCondition != '') {
|
| + rescanDirectoryNeeded = true;
|
| + }
|
| + }
|
| // TODO(dgozman): rescan directory, only if it contains mounted points,
|
| // when mounts location will be decided.
|
| - if (event.status == 'success' ||
|
| - event.status == 'error_unknown_filesystem' ||
|
| - event.status == 'error_unsuported_filesystem')
|
| + if (rescanDirectoryNeeded)
|
| self.rescanDirectory_(null, 300);
|
| });
|
| };
|
| @@ -1841,6 +1869,17 @@ FileManager.prototype = {
|
| }
|
| };
|
|
|
| + FileManager.prototype.getDeviceNumber = function(entry) {
|
| + if (!entry.isDirectory) return false;
|
| + for (var i = 0; i < this.mountPoints_.length; i++) {
|
| + if (normalizeAbsolutePath(entry.fullPath) ==
|
| + normalizeAbsolutePath(this.mountPoints_[i].mountPath)) {
|
| + return i;
|
| + }
|
| + }
|
| + return undefined;
|
| + }
|
| +
|
| FileManager.prototype.openImageEditor_ = function(entry) {
|
| var self = this;
|
|
|
| @@ -1945,7 +1984,7 @@ FileManager.prototype = {
|
|
|
| this.previewFilename_.textContent = previewName;
|
|
|
| - var iconType = getIconType(this.selection.leadEntry);
|
| + var iconType = this.getIconType(this.selection.leadEntry);
|
| if (iconType == 'image') {
|
| if (fileManager.selection.totalCount > 1)
|
| this.previewImage_.classList.add('multiple-selected');
|
| @@ -2102,7 +2141,7 @@ FileManager.prototype = {
|
| if (!entry)
|
| return;
|
|
|
| - var iconType = getIconType(entry);
|
| + var iconType = this.getIconType(entry);
|
|
|
| this.cacheMetadata_(entry, function (metadata) {
|
| var url = metadata.thumbnailURL;
|
| @@ -2502,14 +2541,30 @@ FileManager.prototype = {
|
| return;
|
| }
|
|
|
| - if (entry.isDirectory)
|
| - return this.changeDirectory(entry.fullPath);
|
| + if (entry.isDirectory) {
|
| + return this.onDirectoryAction(entry);
|
| + }
|
|
|
| if (!this.okButton_.disabled)
|
| this.onOk_();
|
|
|
| };
|
|
|
| + FileManager.prototype.onDirectoryAction = function(entry) {
|
| + var deviceNumber = this.getDeviceNumber(entry);
|
| + if (deviceNumber != undefined &&
|
| + this.mountPoints_[deviceNumber].mountCondition ==
|
| + 'unknown_filesystem') {
|
| + return this.showButter(str('UNKNOWN_FILESYSTEM_WARNING'));
|
| + } else if (deviceNumber != undefined &&
|
| + this.mountPoints_[deviceNumber].mountCondition ==
|
| + 'unsupported_filesystem') {
|
| + return this.showButter(str('UNSUPPORTED_FILESYSTEM_WARNING'));
|
| + } else {
|
| + return this.changeDirectory(entry.fullPath);
|
| + }
|
| + }
|
| +
|
| /**
|
| * Update the UI when the current directory changes.
|
| *
|
| @@ -2972,7 +3027,7 @@ FileManager.prototype = {
|
| this.selection.leadEntry.isDirectory &&
|
| this.dialogType_ != FileManager.SELECT_FOLDER) {
|
| event.preventDefault();
|
| - this.changeDirectory(this.selection.leadEntry.fullPath);
|
| + this.onDirectoryAction(this.selection.leadEntry);
|
| } else if (!this.okButton_.disabled) {
|
| event.preventDefault();
|
| this.onOk_();
|
|
|