| 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 e4e044ed8d5a468c8935a5d7f47988e9ea5969f6..88b749885894b246ed468171c405ca354fe7abe6 100644
|
| --- a/chrome/browser/resources/file_manager/js/file_manager.js
|
| +++ b/chrome/browser/resources/file_manager/js/file_manager.js
|
| @@ -206,10 +206,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 = {
|
| @@ -218,13 +218,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'
|
| };
|
|
|
| @@ -292,50 +312,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.
|
| *
|
| @@ -477,27 +466,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 ||
|
| @@ -658,6 +626,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) {
|
| @@ -1243,7 +1273,7 @@ FileManager.prototype = {
|
| } else if (field == 'cachedSize_') {
|
| cacheFunction = cacheEntrySize;
|
| } else if (field == 'cachedIconType_') {
|
| - cacheFunction = cacheEntryIconType;
|
| + cacheFunction = this.cacheEntryIconType;
|
| } else {
|
| callback();
|
| return;
|
| @@ -1350,7 +1380,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);
|
|
|
| @@ -1485,9 +1515,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';
|
| }
|
| @@ -1706,19 +1736,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 = {
|
| @@ -1735,7 +1757,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;
|
| @@ -1789,11 +1812,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_();
|
| });
|
| };
|
| @@ -1828,6 +1856,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;
|
|
|
| @@ -1932,7 +1971,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');
|
| @@ -2089,7 +2128,7 @@ FileManager.prototype = {
|
| if (!entry)
|
| return;
|
|
|
| - var iconType = getIconType(entry);
|
| + var iconType = this.getIconType(entry);
|
|
|
| this.cacheMetadata_(entry, function (metadata) {
|
| var url = metadata.thumbnailURL;
|
| @@ -2489,14 +2528,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.
|
| *
|
| @@ -2908,7 +2963,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_();
|
|
|