Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1043)

Side by Side Diff: chrome/browser/resources/file_manager/js/file_manager.js

Issue 7584004: Keeping the current directory in URL. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Conflicts resolved. Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 // Setting the src of an img to an empty string can crash the browser, so we 5 // Setting the src of an img to an empty string can crash the browser, so we
6 // use an empty 1x1 gif instead. 6 // use an empty 1x1 gif instead.
7 const EMPTY_IMAGE_URI = 'data:image/gif;base64,' 7 const EMPTY_IMAGE_URI = 'data:image/gif;base64,'
8 + 'R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw%3D%3D'; 8 + 'R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw%3D%3D';
9 9
10 var g_slideshow_data = null; 10 var g_slideshow_data = null;
(...skipping 13 matching lines...) Expand all
24 * the root filesystem for the new FileManager. 24 * the root filesystem for the new FileManager.
25 * @param {Object} params A map of parameter names to values controlling the 25 * @param {Object} params A map of parameter names to values controlling the
26 * appearance of the FileManager. Names are: 26 * appearance of the FileManager. Names are:
27 * - type: A value from FileManager.DialogType defining what kind of 27 * - type: A value from FileManager.DialogType defining what kind of
28 * dialog to present. Defaults to FULL_PAGE. 28 * dialog to present. Defaults to FULL_PAGE.
29 * - title: The title for the dialog. Defaults to a localized string based 29 * - title: The title for the dialog. Defaults to a localized string based
30 * on the dialog type. 30 * on the dialog type.
31 * - defaultPath: The default path for the dialog. The default path should 31 * - defaultPath: The default path for the dialog. The default path should
32 * end with a trailing slash if it represents a directory. 32 * end with a trailing slash if it represents a directory.
33 */ 33 */
34 function FileManager(dialogDom, filesystem, rootEntries, params) { 34 function FileManager(dialogDom, filesystem, rootEntries) {
35 console.log('Init FileManager: ' + dialogDom); 35 console.log('Init FileManager: ' + dialogDom);
36 36
37 this.dialogDom_ = dialogDom; 37 this.dialogDom_ = dialogDom;
38 this.rootEntries_ = rootEntries; 38 this.rootEntries_ = rootEntries;
39 this.filesystem_ = filesystem; 39 this.filesystem_ = filesystem;
40 this.params_ = params || {}; 40 this.params_ = location.search ?
41 JSON.parse(decodeURIComponent(location.search.substr(1))) :
42 {};
41 43
42 this.listType_ = null; 44 this.listType_ = null;
43 45
44 this.metadataCache_ = {}; 46 this.metadataCache_ = {};
45 47
46 this.selection = null; 48 this.selection = null;
47 49
48 this.clipboard_ = null; // Current clipboard, or null if empty. 50 this.clipboard_ = null; // Current clipboard, or null if empty.
49 51
50 this.butterTimer_ = null; 52 this.butterTimer_ = null;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 chrome.fileBrowserPrivate.getMountPoints(function(mountPoints) { 127 chrome.fileBrowserPrivate.getMountPoints(function(mountPoints) {
126 self.mountPoints_ = mountPoints; 128 self.mountPoints_ = mountPoints;
127 }); 129 });
128 130
129 chrome.fileBrowserHandler.onExecute.addListener( 131 chrome.fileBrowserHandler.onExecute.addListener(
130 this.onFileTaskExecute_.bind(this)); 132 this.onFileTaskExecute_.bind(this));
131 133
132 this.initCommands_(); 134 this.initCommands_();
133 this.initDom_(); 135 this.initDom_();
134 this.initDialogType_(); 136 this.initDialogType_();
135 this.initDefaultDirectory_(this.params_.defaultPath); 137 this.setupCurrentDirectory_();
136 138
137 this.summarizeSelection_(); 139 this.summarizeSelection_();
138 this.updatePreview_(); 140 this.updatePreview_();
139 141
140 chrome.fileBrowserPrivate.onDiskChanged.addListener( 142 chrome.fileBrowserPrivate.onDiskChanged.addListener(
141 this.onDiskChanged_.bind(this)); 143 this.onDiskChanged_.bind(this));
142 144
143 this.refocus(); 145 this.refocus();
144 146
145 // Pass all URLs to the metadata reader until we have a correct filter. 147 // Pass all URLs to the metadata reader until we have a correct filter.
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 this.pasteButton_.disabled = !event.canExecute; 813 this.pasteButton_.disabled = !event.canExecute;
812 break; 814 break;
813 815
814 case 'rename': 816 case 'rename':
815 event.canExecute = 817 event.canExecute =
816 (// Initialized to the point where we have a current directory 818 (// Initialized to the point where we have a current directory
817 this.currentDirEntry_ && 819 this.currentDirEntry_ &&
818 // Rename not in progress. 820 // Rename not in progress.
819 !this.renameInput_.currentEntry && 821 !this.renameInput_.currentEntry &&
820 // Only one file selected. 822 // Only one file selected.
823 this.selection &&
821 this.selection.totalCount == 1 && 824 this.selection.totalCount == 1 &&
822 !isSystemDirEntry(this.currentDirEntry_)); 825 !isSystemDirEntry(this.currentDirEntry_));
823 break; 826 break;
824 827
825 case 'delete': 828 case 'delete':
826 event.canExecute = 829 event.canExecute =
827 (// Initialized to the point where we have a current directory 830 (// Initialized to the point where we have a current directory
828 this.currentDirEntry_ && 831 this.currentDirEntry_ &&
829 // Rename not in progress. 832 // Rename not in progress.
830 !this.renameInput_.currentEntry && 833 !this.renameInput_.currentEntry &&
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 this.initiateRename_(label); 1016 this.initiateRename_(label);
1014 return; 1017 return;
1015 1018
1016 case 'delete': 1019 case 'delete':
1017 this.deleteEntries(this.selection.entries); 1020 this.deleteEntries(this.selection.entries);
1018 return; 1021 return;
1019 } 1022 }
1020 }; 1023 };
1021 1024
1022 /** 1025 /**
1023 * Respond to the back button. 1026 * Respond to the back and forward buttons.
1024 */ 1027 */
1025 FileManager.prototype.onPopState_ = function(event) { 1028 FileManager.prototype.onPopState_ = function(event) {
1026 this.changeDirectory(event.state, CD_NO_HISTORY); 1029 // TODO(serya): We should restore selected items here.
1030 this.setupCurrentDirectory_();
1027 }; 1031 };
1028 1032
1029 FileManager.prototype.requestResize_ = function(timeout) { 1033 FileManager.prototype.requestResize_ = function(timeout) {
1030 var self = this; 1034 var self = this;
1031 setTimeout(function() { self.onResize_() }, timeout || 0); 1035 setTimeout(function() { self.onResize_() }, timeout || 0);
1032 }; 1036 };
1033 1037
1034 /** 1038 /**
1035 * Resize details and thumb views to fit the new window size. 1039 * Resize details and thumb views to fit the new window size.
1036 */ 1040 */
(...skipping 17 matching lines...) Expand all
1054 this.currentList_.redraw(); 1058 this.currentList_.redraw();
1055 } 1059 }
1056 }; 1060 };
1057 1061
1058 FileManager.prototype.resolvePath = function( 1062 FileManager.prototype.resolvePath = function(
1059 path, resultCallback, errorCallback) { 1063 path, resultCallback, errorCallback) {
1060 return util.resolvePath(this.filesystem_.root, path, resultCallback, 1064 return util.resolvePath(this.filesystem_.root, path, resultCallback,
1061 errorCallback); 1065 errorCallback);
1062 }; 1066 };
1063 1067
1064 FileManager.prototype.initDefaultDirectory_ = function(path) { 1068 /**
1065 if (!path) { 1069 * Restores current directory and may be a selected item after page load (or
1066 // No preset given, find a good place to start. 1070 * reload) or popping a state (after click on back/forward). If location.hash
1067 // Check for removable devices, if there are none, go to Downloads. 1071 * is present it means that the user has navigated somewhere and that place
1068 for (var i = 0; i != this.rootEntries_.length; i++) { 1072 * will be restored. defaultPath primarily is used with save/open dialogs.
1069 var rootEntry = this.rootEntries_[i]; 1073 * Default path may also contain a file name. Freshly opened file manager
1070 if (rootEntry.fullPath == REMOVABLE_DIRECTORY) { 1074 * window has neither.
1071 var foundRemovable = false; 1075 */
1072 var self = this; 1076 FileManager.prototype.setupCurrentDirectory_ = function() {
1073 util.forEachDirEntry(rootEntry, function(result) { 1077 if (location.hash) {
1074 if (result) { 1078 // Location hash has the highest priority.
1075 foundRemovable = true; 1079 var path = decodeURI(location.hash.substr(1));
1076 } else { // Done enumerating, and we know the answer. 1080 this.changeDirectory(path, CD_NO_HISTORY);
1077 self.initDefaultDirectory_( 1081 return;
1078 foundRemovable ? '/' : DOWNLOADS_DIRECTORY); 1082 } else if (this.params_.defaultPath) {
1079 } 1083 this.setupPath_(this.params_.defaultPath);
1080 }); 1084 } else {
1081 return; 1085 this.setupDefaultPath_();
1082 } 1086 }
1083 } 1087 };
1084 1088
1085 // Removable root directory is missing altogether. 1089 FileManager.prototype.setupDefaultPath_ = function() {
1086 path = DOWNLOADS_DIRECTORY; 1090 // No preset given, find a good place to start.
1091 // Check for removable devices, if there are none, go to Downloads.
1092 var removableDirectoryEntry = this.rootEntries_.filter(function(rootEntry) {
1093 return rootEntry.fullPath == REMOVABLE_DIRECTORY;
1094 })[0];
1095 if (!removableDirectoryEntry) {
1096 this.changeDirectory(DOWNLOADS_DIRECTORY, CD_NO_HISTORY);
1097 return;
1087 } 1098 }
1088 1099
1100 var foundRemovable = false;
1101 util.forEachDirEntry(removableDirectoryEntry, function(result) {
1102 if (result) {
1103 foundRemovable = true;
1104 } else { // Done enumerating, and we know the answer.
1105 this.changeDirectory(foundRemovable ? '/' : DOWNLOADS_DIRECTORY,
1106 CD_NO_HISTORY);
1107 }
1108 }.bind(this));
1109 };
1110
1111 FileManager.prototype.setupPath_ = function(path) {
1089 // Split the dirname from the basename. 1112 // Split the dirname from the basename.
1090 var ary = path.match(/^(.*?)(?:\/([^\/]+))?$/); 1113 var ary = path.match(/^(.*?)(?:\/([^\/]+))?$/);
1091 if (!ary) { 1114 if (!ary) {
1092 console.warn('Unable to split default path: ' + path); 1115 console.warn('Unable to split default path: ' + path);
1093 self.changeDirectory('/', CD_NO_HISTORY); 1116 self.changeDirectory('/', CD_NO_HISTORY);
1094 return; 1117 return;
1095 } 1118 }
1096 1119
1097 var baseName = ary[1]; 1120 var baseName = ary[1];
1098 var leafName = ary[2]; 1121 var leafName = ary[2];
(...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after
2015 * 2038 *
2016 * @param {string} path The absolute path to the new directory. 2039 * @param {string} path The absolute path to the new directory.
2017 * @param {bool} opt_saveHistory Save this in the history stack (defaults 2040 * @param {bool} opt_saveHistory Save this in the history stack (defaults
2018 * to true). 2041 * to true).
2019 * @param {string} opt_selectedEntry The name of the file to select after 2042 * @param {string} opt_selectedEntry The name of the file to select after
2020 * changing directories. 2043 * changing directories.
2021 */ 2044 */
2022 FileManager.prototype.changeDirectoryEntry = function(dirEntry, 2045 FileManager.prototype.changeDirectoryEntry = function(dirEntry,
2023 opt_saveHistory, 2046 opt_saveHistory,
2024 opt_selectedEntry) { 2047 opt_selectedEntry) {
2048 if (typeof opt_saveHistory == 'undefined') {
2049 opt_saveHistory = true;
2050 } else {
2051 opt_saveHistory = !!opt_saveHistory;
2052 }
2053
2054 var location = '#' + encodeURI(dirEntry.fullPath);
2055 if (opt_saveHistory) {
2056 history.pushState(undefined, dirEntry.fullPath, location);
2057 } else if (window.location.hash != location) {
2058 // If the user typed URL manually that is not canonical it would be fixed
2059 // here. However it seems history.replaceState doesn't work properly
2060 // with rewritable URLs (while does with history.pushState). It changes
2061 // window.location but doesn't change content of the ombibox.
2062 history.replaceState(undefined, dirEntry.fullPath, location);
2063 }
2064
2025 if (this.currentDirEntry_ && 2065 if (this.currentDirEntry_ &&
2026 this.currentDirEntry_.fullPath == dirEntry.fullPath) { 2066 this.currentDirEntry_.fullPath == dirEntry.fullPath) {
2027 // Directory didn't actually change. 2067 // Directory didn't actually change.
2028 if (opt_selectedEntry) 2068 if (opt_selectedEntry)
2029 this.selectEntry(opt_selectedEntry); 2069 this.selectEntry(opt_selectedEntry);
2030 return; 2070 return;
2031 } 2071 }
2032 2072
2033 if (typeof opt_saveHistory == 'undefined') {
2034 opt_saveHistory = true;
2035 } else {
2036 opt_saveHistory = !!opt_saveHistory;
2037 }
2038
2039 var e = new cr.Event('directory-changed'); 2073 var e = new cr.Event('directory-changed');
2040 e.previousDirEntry = this.currentDirEntry_; 2074 e.previousDirEntry = this.currentDirEntry_;
2041 e.newDirEntry = dirEntry; 2075 e.newDirEntry = dirEntry;
2042 e.saveHistory = opt_saveHistory; 2076 e.saveHistory = opt_saveHistory;
2043 e.selectedEntry = opt_selectedEntry; 2077 e.selectedEntry = opt_selectedEntry;
2044 this.currentDirEntry_ = dirEntry; 2078 this.currentDirEntry_ = dirEntry;
2045 this.dispatchEvent(e); 2079 this.dispatchEvent(e);
2046 } 2080 }
2047 2081
2048 /** 2082 /**
2049 * Change the current directory to the directory represented by a string 2083 * Change the current directory to the directory represented by a string
2050 * path. 2084 * path.
2051 * 2085 *
2052 * Dispatches the 'directory-changed' event when the directory is successfully 2086 * Dispatches the 'directory-changed' event when the directory is successfully
2053 * changed. 2087 * changed.
2054 * 2088 *
2055 * @param {string} path The absolute path to the new directory. 2089 * @param {string} path The absolute path to the new directory.
2056 * @param {bool} opt_saveHistory Save this in the history stack (defaults 2090 * @param {bool} opt_saveHistory Save this in the history stack (defaults
2057 * to true). 2091 * to true).
2058 * @param {string} opt_selectedEntry The name of the file to select after 2092 * @param {string} opt_selectedEntry The name of the file to select after
2059 * changing directories. 2093 * changing directories.
2060 */ 2094 */
2061 FileManager.prototype.changeDirectory = function(path, 2095 FileManager.prototype.changeDirectory = function(path,
2062 opt_saveHistory, 2096 opt_saveHistory,
2063 opt_selectedEntry) { 2097 opt_selectedEntry) {
2064 if (path == '/') 2098 if (path == '/')
2065 return this.changeDirectoryEntry(this.filesystem_.root); 2099 return this.changeDirectoryEntry(this.filesystem_.root,
2100 opt_saveHistory,
2101 opt_selectedEntry);
2066 2102
2067 var self = this; 2103 var self = this;
2068 2104
2069 this.filesystem_.root.getDirectory( 2105 this.filesystem_.root.getDirectory(
2070 path, {create: false}, 2106 path, {create: false},
2071 function(dirEntry) { 2107 function(dirEntry) {
2072 self.changeDirectoryEntry( 2108 self.changeDirectoryEntry(
2073 dirEntry, opt_saveHistory, opt_selectedEntry); 2109 dirEntry, opt_saveHistory, opt_selectedEntry);
2074 }, 2110 },
2075 function(err) { 2111 function(err) {
2076 console.error('Error changing directory to: ' + path + ', ' + err); 2112 console.error('Error changing directory to: ' + path + ', ' + err);
2077 if (!self.currentDirEntry_) { 2113 if (self.currentDirEntry_) {
2114 var location = '#' + encodeURI(self.currentDirEntry_.fullPath);
2115 history.replaceState(undefined,
2116 self.currentDirEntry_.fullPath,
2117 location);
2118 } else {
2078 // If we've never successfully changed to a directory, force them 2119 // If we've never successfully changed to a directory, force them
2079 // to the root. 2120 // to the root.
2080 self.changeDirectory('/', false); 2121 self.changeDirectory('/', false);
2081 } 2122 }
2082 }); 2123 });
2083 }; 2124 };
2084 2125
2085 FileManager.prototype.deleteEntries = function(entries, force) { 2126 FileManager.prototype.deleteEntries = function(entries, force) {
2086 if (!force) { 2127 if (!force) {
2087 var self = this; 2128 var self = this;
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
2359 this.onOk_(); 2400 this.onOk_();
2360 2401
2361 }; 2402 };
2362 2403
2363 /** 2404 /**
2364 * Update the UI when the current directory changes. 2405 * Update the UI when the current directory changes.
2365 * 2406 *
2366 * @param {cr.Event} event The directory-changed event. 2407 * @param {cr.Event} event The directory-changed event.
2367 */ 2408 */
2368 FileManager.prototype.onDirectoryChanged_ = function(event) { 2409 FileManager.prototype.onDirectoryChanged_ = function(event) {
2369 if (event.saveHistory) {
2370 history.pushState(this.currentDirEntry_.fullPath,
2371 this.currentDirEntry_.fullPath,
2372 location.href);
2373 }
2374
2375 if (this.currentDirEntry_.fullPath.substr(0, DOWNLOADS_DIRECTORY.length) == 2410 if (this.currentDirEntry_.fullPath.substr(0, DOWNLOADS_DIRECTORY.length) ==
2376 DOWNLOADS_DIRECTORY) { 2411 DOWNLOADS_DIRECTORY) {
2377 if (this.downloadsWarning_.style.height != DOWNLOADS_WARNING_HEIGHT) { 2412 if (this.downloadsWarning_.style.height != DOWNLOADS_WARNING_HEIGHT) {
2378 // Current path starts with DOWNLOADS_DIRECTORY, show the warning. 2413 // Current path starts with DOWNLOADS_DIRECTORY, show the warning.
2379 this.downloadsWarning_.style.height = DOWNLOADS_WARNING_HEIGHT; 2414 this.downloadsWarning_.style.height = DOWNLOADS_WARNING_HEIGHT;
2380 this.requestResize_(100); 2415 this.requestResize_(100);
2381 } 2416 }
2382 } else { 2417 } else {
2383 if (this.downloadsWarning_.style.height != '0') { 2418 if (this.downloadsWarning_.style.height != '0') {
2384 this.downloadsWarning_.style.height = '0'; 2419 this.downloadsWarning_.style.height = '0';
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
2847 case 69: // Ctrl-E => Rename. 2882 case 69: // Ctrl-E => Rename.
2848 this.updateCommands_(); 2883 this.updateCommands_();
2849 if (!this.commands_['rename'].disabled) { 2884 if (!this.commands_['rename'].disabled) {
2850 event.preventDefault(); 2885 event.preventDefault();
2851 this.commands_['rename'].execute(); 2886 this.commands_['rename'].execute();
2852 } 2887 }
2853 break; 2888 break;
2854 2889
2855 case 46: // Delete. 2890 case 46: // Delete.
2856 if (this.dialogType_ == FileManager.DialogType.FULL_PAGE && 2891 if (this.dialogType_ == FileManager.DialogType.FULL_PAGE &&
2857 this.selection.totalCount > 0 && 2892 this.selection && this.selection.totalCount > 0 &&
2858 !isSystemDirEntry(this.currentDirEntry_)) { 2893 !isSystemDirEntry(this.currentDirEntry_)) {
2859 event.preventDefault(); 2894 event.preventDefault();
2860 this.deleteEntries(this.selection.entries); 2895 this.deleteEntries(this.selection.entries);
2861 } 2896 }
2862 break; 2897 break;
2863 } 2898 }
2864 }; 2899 };
2865 2900
2866 /** 2901 /**
2867 * KeyPress event handler for the div.list-container element. 2902 * KeyPress event handler for the div.list-container element.
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
3045 3080
3046 if (msg) { 3081 if (msg) {
3047 console.log('no no no'); 3082 console.log('no no no');
3048 this.alert.show(msg, onAccept); 3083 this.alert.show(msg, onAccept);
3049 return false; 3084 return false;
3050 } 3085 }
3051 3086
3052 return true; 3087 return true;
3053 }; 3088 };
3054 })(); 3089 })();
OLDNEW
« no previous file with comments | « chrome/browser/extensions/file_manager_util.cc ('k') | chrome/browser/resources/file_manager/js/main.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698