OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 'use strict'; | 5 'use strict'; |
6 | 6 |
7 /** | 7 /** |
8 * FileManager constructor. | 8 * FileManager constructor. |
9 * | 9 * |
10 * FileManager objects encapsulate the functionality of the file selector | 10 * FileManager objects encapsulate the functionality of the file selector |
(...skipping 1921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1932 * @private | 1932 * @private |
1933 */ | 1933 */ |
1934 FileManager.prototype.focusCurrentList_ = function() { | 1934 FileManager.prototype.focusCurrentList_ = function() { |
1935 if (this.listType_ == FileManager.ListType.DETAIL) | 1935 if (this.listType_ == FileManager.ListType.DETAIL) |
1936 this.table_.focus(); | 1936 this.table_.focus(); |
1937 else // this.listType_ == FileManager.ListType.THUMBNAIL) | 1937 else // this.listType_ == FileManager.ListType.THUMBNAIL) |
1938 this.grid_.focus(); | 1938 this.grid_.focus(); |
1939 }; | 1939 }; |
1940 | 1940 |
1941 /** | 1941 /** |
1942 * Return full path of the current directory or null. | |
1943 * @return {?string} The full path of the current directory. | |
1944 */ | |
1945 FileManager.prototype.getCurrentDirectory = function() { | |
1946 return this.directoryModel_ && this.directoryModel_.getCurrentDirPath(); | |
1947 }; | |
1948 | |
1949 /** | |
1950 * Return URL of the current directory or null. | |
1951 * @return {string} URL representing the current directory. | |
1952 */ | |
1953 FileManager.prototype.getCurrentDirectoryURL = function() { | |
1954 return this.directoryModel_ && | |
1955 this.directoryModel_.getCurrentDirectoryURL(); | |
1956 }; | |
1957 | |
1958 /** | |
1959 * Return DirectoryEntry of the current directory or null. | 1942 * Return DirectoryEntry of the current directory or null. |
1960 * @return {DirectoryEntry} DirectoryEntry of the current directory. Returns | 1943 * @return {DirectoryEntry} DirectoryEntry of the current directory. Returns |
1961 * null if the directory model is not ready or the current directory is | 1944 * null if the directory model is not ready or the current directory is |
1962 * not set. | 1945 * not set. |
1963 */ | 1946 */ |
1964 FileManager.prototype.getCurrentDirectoryEntry = function() { | 1947 FileManager.prototype.getCurrentDirectoryEntry = function() { |
1965 return this.directoryModel_ && this.directoryModel_.getCurrentDirEntry(); | 1948 return this.directoryModel_ && this.directoryModel_.getCurrentDirEntry(); |
1966 }; | 1949 }; |
1967 | 1950 |
1968 /** | 1951 /** |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2199 }; | 2182 }; |
2200 | 2183 |
2201 /** | 2184 /** |
2202 * Update the window title. | 2185 * Update the window title. |
2203 * @private | 2186 * @private |
2204 */ | 2187 */ |
2205 FileManager.prototype.updateTitle_ = function() { | 2188 FileManager.prototype.updateTitle_ = function() { |
2206 if (this.dialogType != DialogType.FULL_PAGE) | 2189 if (this.dialogType != DialogType.FULL_PAGE) |
2207 return; | 2190 return; |
2208 | 2191 |
2209 var path = this.getCurrentDirectory(); | 2192 // TODO(mtomasz): Use VolumeInfo.root instead. |
| 2193 var path = this.getCurrentDirectoryEntry().fullPath; |
2210 var rootPath = PathUtil.getRootPath(path); | 2194 var rootPath = PathUtil.getRootPath(path); |
2211 this.document_.title = PathUtil.getRootLabel(rootPath) + | 2195 this.document_.title = PathUtil.getRootLabel(rootPath) + |
2212 path.substring(rootPath.length); | 2196 path.substring(rootPath.length); |
2213 }; | 2197 }; |
2214 | 2198 |
2215 /** | 2199 /** |
2216 * Update the gear menu. | 2200 * Update the gear menu. |
2217 * @private | 2201 * @private |
2218 */ | 2202 */ |
2219 FileManager.prototype.updateGearMenu_ = function() { | 2203 FileManager.prototype.updateGearMenu_ = function() { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2264 | 2248 |
2265 /** | 2249 /** |
2266 * Update the UI when the current directory changes. | 2250 * Update the UI when the current directory changes. |
2267 * | 2251 * |
2268 * @param {Event} event The directory-changed event. | 2252 * @param {Event} event The directory-changed event. |
2269 * @private | 2253 * @private |
2270 */ | 2254 */ |
2271 FileManager.prototype.onDirectoryChanged_ = function(event) { | 2255 FileManager.prototype.onDirectoryChanged_ = function(event) { |
2272 this.selectionHandler_.onFileSelectionChanged(); | 2256 this.selectionHandler_.onFileSelectionChanged(); |
2273 this.ui_.searchBox.clear(); | 2257 this.ui_.searchBox.clear(); |
2274 util.updateAppState(this.getCurrentDirectory()); | 2258 // TODO(mtomasz): Use Entry.toURL() instead of fullPath. |
| 2259 util.updateAppState( |
| 2260 this.getCurrentDirectoryEntry() && |
| 2261 this.getCurrentDirectoryEntry().fullPath); |
2275 | 2262 |
2276 // If the current directory is moved from the device's volume, do not | 2263 // If the current directory is moved from the device's volume, do not |
2277 // automatically close the window on device removal. | 2264 // automatically close the window on device removal. |
2278 if (event.previousDirEntry && | 2265 if (event.previousDirEntry && |
2279 PathUtil.getRootPath(event.previousDirEntry.fullPath) != | 2266 PathUtil.getRootPath(event.previousDirEntry.fullPath) != |
2280 PathUtil.getRootPath(event.newDirEntry.fullPath)) | 2267 PathUtil.getRootPath(event.newDirEntry.fullPath)) |
2281 this.closeOnUnmount_ = false; | 2268 this.closeOnUnmount_ = false; |
2282 | 2269 |
2283 if (this.commandHandler) | 2270 if (this.commandHandler) |
2284 this.commandHandler.updateAvailability(); | 2271 this.commandHandler.updateAvailability(); |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2486 newName); | 2473 newName); |
2487 } else { | 2474 } else { |
2488 message = strf('ERROR_RENAMING', entry.name, | 2475 message = strf('ERROR_RENAMING', entry.name, |
2489 util.getFileErrorString(err.code)); | 2476 util.getFileErrorString(err.code)); |
2490 } | 2477 } |
2491 | 2478 |
2492 this.alert.show(message); | 2479 this.alert.show(message); |
2493 }.bind(this)); | 2480 }.bind(this)); |
2494 }; | 2481 }; |
2495 | 2482 |
2496 // TODO(haruki): this.getCurrentDirectoryURL() might not return the actual | 2483 // TODO(haruki): this.getCurrentDirectoryEntry() might not return the actual |
2497 // parent if the directory content is a search result. Fix it to do proper | 2484 // parent if the directory content is a search result. Fix it to do proper |
2498 // validation. | 2485 // validation. |
2499 this.validateFileName_(this.getCurrentDirectoryURL(), | 2486 this.validateFileName_(this.getCurrentDirectoryEntry(), |
2500 newName, | 2487 newName, |
2501 validationDone.bind(this)); | 2488 validationDone.bind(this)); |
2502 }; | 2489 }; |
2503 | 2490 |
2504 /** | 2491 /** |
2505 * @private | 2492 * @private |
2506 */ | 2493 */ |
2507 FileManager.prototype.cancelRename_ = function() { | 2494 FileManager.prototype.cancelRename_ = function() { |
2508 this.renameInput_.currentEntry = null; | 2495 this.renameInput_.currentEntry = null; |
2509 | 2496 |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2834 */ | 2821 */ |
2835 FileManager.prototype.onListKeyDown_ = function(event) { | 2822 FileManager.prototype.onListKeyDown_ = function(event) { |
2836 if (event.srcElement.tagName == 'INPUT') { | 2823 if (event.srcElement.tagName == 'INPUT') { |
2837 // Ignore keydown handler in the rename input box. | 2824 // Ignore keydown handler in the rename input box. |
2838 return; | 2825 return; |
2839 } | 2826 } |
2840 | 2827 |
2841 switch (util.getKeyModifiers(event) + event.keyCode) { | 2828 switch (util.getKeyModifiers(event) + event.keyCode) { |
2842 case '8': // Backspace => Up one directory. | 2829 case '8': // Backspace => Up one directory. |
2843 event.preventDefault(); | 2830 event.preventDefault(); |
2844 var path = this.getCurrentDirectory(); | 2831 // TODO(mtomasz): Use Entry.getParent() instead. |
| 2832 if (!this.getCurrentDirectoryEntry()) |
| 2833 break; |
| 2834 var path = this.getCurrentDirectoryEntry().fullPath; |
2845 if (path && !PathUtil.isRootPath(path)) { | 2835 if (path && !PathUtil.isRootPath(path)) { |
2846 var path = path.replace(/\/[^\/]+$/, ''); | 2836 var path = path.replace(/\/[^\/]+$/, ''); |
2847 this.directoryModel_.changeDirectory(path); | 2837 this.directoryModel_.changeDirectory(path); |
2848 } | 2838 } |
2849 break; | 2839 break; |
2850 | 2840 |
2851 case '13': // Enter => Change directory or perform default action. | 2841 case '13': // Enter => Change directory or perform default action. |
2852 // TODO(dgozman): move directory action to dispatchSelectionAction. | 2842 // TODO(dgozman): move directory action to dispatchSelectionAction. |
2853 var selection = this.getSelection(); | 2843 var selection = this.getSelection(); |
2854 if (selection.totalCount == 1 && | 2844 if (selection.totalCount == 1 && |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3125 */ | 3115 */ |
3126 FileManager.prototype.onOk_ = function(event) { | 3116 FileManager.prototype.onOk_ = function(event) { |
3127 if (this.dialogType == DialogType.SELECT_SAVEAS_FILE) { | 3117 if (this.dialogType == DialogType.SELECT_SAVEAS_FILE) { |
3128 // Save-as doesn't require a valid selection from the list, since | 3118 // Save-as doesn't require a valid selection from the list, since |
3129 // we're going to take the filename from the text input. | 3119 // we're going to take the filename from the text input. |
3130 var filename = this.filenameInput_.value; | 3120 var filename = this.filenameInput_.value; |
3131 if (!filename) | 3121 if (!filename) |
3132 throw new Error('Missing filename!'); | 3122 throw new Error('Missing filename!'); |
3133 | 3123 |
3134 var directory = this.getCurrentDirectoryEntry(); | 3124 var directory = this.getCurrentDirectoryEntry(); |
3135 var currentDirUrl = directory.toURL(); | 3125 this.validateFileName_(directory, filename, function(isValid) { |
3136 if (currentDirUrl.charAt(currentDirUrl.length - 1) != '/') | |
3137 currentDirUrl += '/'; | |
3138 this.validateFileName_(currentDirUrl, filename, function(isValid) { | |
3139 if (!isValid) | 3126 if (!isValid) |
3140 return; | 3127 return; |
3141 | 3128 |
3142 if (util.isFakeEntry(directory)) { | 3129 if (util.isFakeEntry(directory)) { |
3143 // Can't save a file into a fake directory. | 3130 // Can't save a file into a fake directory. |
3144 return; | 3131 return; |
3145 } | 3132 } |
3146 | 3133 |
3147 var selectFileAndClose = function() { | 3134 var selectFileAndClose = function() { |
| 3135 // TODO(mtomasz): Clean this up by avoiding constructing a URL |
| 3136 // via string concatenation. |
| 3137 var currentDirUrl = directory.toURL(); |
| 3138 if (currentDirUrl.charAt(currentDirUrl.length - 1) != '/') |
| 3139 currentDirUrl += '/'; |
3148 this.selectFilesAndClose_({ | 3140 this.selectFilesAndClose_({ |
3149 urls: [currentDirUrl + encodeURIComponent(filename)], | 3141 urls: [currentDirUrl + encodeURIComponent(filename)], |
3150 multiple: false, | 3142 multiple: false, |
3151 filterIndex: this.getSelectedFilterIndex_(filename) | 3143 filterIndex: this.getSelectedFilterIndex_(filename) |
3152 }); | 3144 }); |
3153 }.bind(this); | 3145 }.bind(this); |
3154 | 3146 |
3155 directory.getFile( | 3147 directory.getFile( |
3156 filename, {create: false}, | 3148 filename, {create: false}, |
3157 function(entry) { | 3149 function(entry) { |
(...skipping 21 matching lines...) Expand all Loading... |
3179 }.bind(this)); | 3171 }.bind(this)); |
3180 }.bind(this)); | 3172 }.bind(this)); |
3181 return; | 3173 return; |
3182 } | 3174 } |
3183 | 3175 |
3184 var files = []; | 3176 var files = []; |
3185 var selectedIndexes = this.currentList_.selectionModel.selectedIndexes; | 3177 var selectedIndexes = this.currentList_.selectionModel.selectedIndexes; |
3186 | 3178 |
3187 if (DialogType.isFolderDialog(this.dialogType) && | 3179 if (DialogType.isFolderDialog(this.dialogType) && |
3188 selectedIndexes.length == 0) { | 3180 selectedIndexes.length == 0) { |
3189 var url = this.getCurrentDirectoryURL(); | 3181 var url = this.getCurrentDirectoryEntry().toURL(); |
3190 var singleSelection = { | 3182 var singleSelection = { |
3191 urls: [url], | 3183 urls: [url], |
3192 multiple: false, | 3184 multiple: false, |
3193 filterIndex: this.getSelectedFilterIndex_() | 3185 filterIndex: this.getSelectedFilterIndex_() |
3194 }; | 3186 }; |
3195 this.selectFilesAndClose_(singleSelection); | 3187 this.selectFilesAndClose_(singleSelection); |
3196 return; | 3188 return; |
3197 } | 3189 } |
3198 | 3190 |
3199 // All other dialog types require at least one selected list item. | 3191 // All other dialog types require at least one selected list item. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3248 /** | 3240 /** |
3249 * Verifies the user entered name for file or folder to be created or | 3241 * Verifies the user entered name for file or folder to be created or |
3250 * renamed to. Name restrictions must correspond to File API restrictions | 3242 * renamed to. Name restrictions must correspond to File API restrictions |
3251 * (see DOMFilePath::isValidPath). Curernt WebKit implementation is | 3243 * (see DOMFilePath::isValidPath). Curernt WebKit implementation is |
3252 * out of date (spec is | 3244 * out of date (spec is |
3253 * http://dev.w3.org/2009/dap/file-system/file-dir-sys.html, 8.3) and going to | 3245 * http://dev.w3.org/2009/dap/file-system/file-dir-sys.html, 8.3) and going to |
3254 * be fixed. Shows message box if the name is invalid. | 3246 * be fixed. Shows message box if the name is invalid. |
3255 * | 3247 * |
3256 * It also verifies if the name length is in the limit of the filesystem. | 3248 * It also verifies if the name length is in the limit of the filesystem. |
3257 * | 3249 * |
3258 * @param {string} parentUrl The URL of the parent directory entry. | 3250 * @param {DirectoryEntry} parentEntry The URL of the parent directory entry. |
3259 * @param {string} name New file or folder name. | 3251 * @param {string} name New file or folder name. |
3260 * @param {function} onDone Function to invoke when user closes the | 3252 * @param {function} onDone Function to invoke when user closes the |
3261 * warning box or immediatelly if file name is correct. If the name was | 3253 * warning box or immediatelly if file name is correct. If the name was |
3262 * valid it is passed true, and false otherwise. | 3254 * valid it is passed true, and false otherwise. |
3263 * @private | 3255 * @private |
3264 */ | 3256 */ |
3265 FileManager.prototype.validateFileName_ = function(parentUrl, name, onDone) { | 3257 FileManager.prototype.validateFileName_ = function( |
| 3258 parentEntry, name, onDone) { |
3266 var msg; | 3259 var msg; |
3267 var testResult = /[\/\\\<\>\:\?\*\"\|]/.exec(name); | 3260 var testResult = /[\/\\\<\>\:\?\*\"\|]/.exec(name); |
3268 if (testResult) { | 3261 if (testResult) { |
3269 msg = strf('ERROR_INVALID_CHARACTER', testResult[0]); | 3262 msg = strf('ERROR_INVALID_CHARACTER', testResult[0]); |
3270 } else if (/^\s*$/i.test(name)) { | 3263 } else if (/^\s*$/i.test(name)) { |
3271 msg = str('ERROR_WHITESPACE_NAME'); | 3264 msg = str('ERROR_WHITESPACE_NAME'); |
3272 } else if (/^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/i.test(name)) { | 3265 } else if (/^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/i.test(name)) { |
3273 msg = str('ERROR_RESERVED_NAME'); | 3266 msg = str('ERROR_RESERVED_NAME'); |
3274 } else if (this.fileFilter_.isFilterHiddenOn() && name[0] == '.') { | 3267 } else if (this.fileFilter_.isFilterHiddenOn() && name[0] == '.') { |
3275 msg = str('ERROR_HIDDEN_NAME'); | 3268 msg = str('ERROR_HIDDEN_NAME'); |
3276 } | 3269 } |
3277 | 3270 |
3278 if (msg) { | 3271 if (msg) { |
3279 this.alert.show(msg, function() { | 3272 this.alert.show(msg, function() { |
3280 onDone(false); | 3273 onDone(false); |
3281 }); | 3274 }); |
3282 return; | 3275 return; |
3283 } | 3276 } |
3284 | 3277 |
3285 var self = this; | 3278 var self = this; |
3286 chrome.fileBrowserPrivate.validatePathNameLength( | 3279 chrome.fileBrowserPrivate.validatePathNameLength( |
3287 parentUrl, name, function(valid) { | 3280 parentEntry.toURL(), name, function(valid) { |
3288 if (!valid) { | 3281 if (!valid) { |
3289 self.alert.show(str('ERROR_LONG_NAME'), | 3282 self.alert.show(str('ERROR_LONG_NAME'), |
3290 function() { onDone(false); }); | 3283 function() { onDone(false); }); |
3291 } else { | 3284 } else { |
3292 onDone(true); | 3285 onDone(true); |
3293 } | 3286 } |
3294 }); | 3287 }); |
3295 }; | 3288 }; |
3296 | 3289 |
3297 /** | 3290 /** |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3644 callback(this.preferences_); | 3637 callback(this.preferences_); |
3645 return; | 3638 return; |
3646 } | 3639 } |
3647 | 3640 |
3648 chrome.fileBrowserPrivate.getPreferences(function(prefs) { | 3641 chrome.fileBrowserPrivate.getPreferences(function(prefs) { |
3649 this.preferences_ = prefs; | 3642 this.preferences_ = prefs; |
3650 callback(prefs); | 3643 callback(prefs); |
3651 }.bind(this)); | 3644 }.bind(this)); |
3652 }; | 3645 }; |
3653 })(); | 3646 })(); |
OLD | NEW |