Commit 49788eff authored by yzshen@chromium.org's avatar yzshen@chromium.org

Revert 95621 - Keeping the current directory in URL.

It makes the refresh button on the file manager working in intuitive manner. Also now it's possible to set a bookmark to a specific directory or enter directory path in the omnibox.

BUG=chromium-os:17787
TEST=None


Review URL: http://codereview.chromium.org/7584004

TBR=serya@chromium.org
Review URL: http://codereview.chromium.org/7550035

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@95625 0039d316-1c4b-4281-b951-d872f2087c98
parent 29854223
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_list.h"
#include "chrome/common/url_constants.h"
#include "content/browser/browser_thread.h" #include "content/browser/browser_thread.h"
#include "content/browser/user_metrics.h" #include "content/browser/user_metrics.h"
#include "grit/generated_resources.h" #include "grit/generated_resources.h"
...@@ -153,65 +152,25 @@ GURL FileManagerUtil::GetFileBrowserUrlWithParams( ...@@ -153,65 +152,25 @@ GURL FileManagerUtil::GetFileBrowserUrlWithParams(
const SelectFileDialog::FileTypeInfo* file_types, const SelectFileDialog::FileTypeInfo* file_types,
int file_type_index, int file_type_index,
const FilePath::StringType& default_extension) { const FilePath::StringType& default_extension) {
DictionaryValue arg_value; std::string json = GetArgumentsJson(type, title, default_virtual_path,
arg_value.SetString("type", GetDialogTypeAsString(type)); file_types, file_type_index,
arg_value.SetString("title", title); default_extension);
arg_value.SetString("defaultPath", default_virtual_path.value()); return GURL(FileManagerUtil::GetFileBrowserUrl().spec() + "?" +
arg_value.SetString("defaultExtension", default_extension); EscapeUrlEncodedData(json, false));
if (file_types) {
ListValue* types_list = new ListValue();
for (size_t i = 0; i < file_types->extensions.size(); ++i) {
ListValue* extensions_list = new ListValue();
for (size_t j = 0; j < file_types->extensions[i].size(); ++j) {
extensions_list->Set(
i, Value::CreateStringValue(file_types->extensions[i][j]));
}
DictionaryValue* dict = new DictionaryValue();
dict->Set("extensions", extensions_list);
if (i < file_types->extension_description_overrides.size()) {
string16 desc = file_types->extension_description_overrides[i];
dict->SetString("description", desc);
}
dict->SetBoolean("selected",
(static_cast<size_t>(file_type_index) == i));
types_list->Set(i, dict);
}
arg_value.Set("typeList", types_list);
}
std::string json_args;
base::JSONWriter::Write(&arg_value, false, &json_args);
// kChromeUIFileManagerURL could not be used since query parameters are not
// supported for it.
std::string url = FileManagerUtil::GetFileBrowserUrl().spec() +
'?' + EscapeUrlEncodedData(json_args, false);
return GURL(url);
} }
// static // static
void FileManagerUtil::ShowFullTabUrl(Profile*, void FileManagerUtil::ShowFullTabUrl(Profile*,
const FilePath& dir) { const FilePath& default_path) {
std::string json = GetArgumentsJson(SelectFileDialog::SELECT_NONE, string16(),
default_path, NULL, 0, FilePath::StringType());
GURL url(std::string(kBaseFileBrowserUrl) + "?" +
EscapeUrlEncodedData(json, false));
Browser* browser = BrowserList::GetLastActive(); Browser* browser = BrowserList::GetLastActive();
if (!browser) if (!browser)
return; return;
FilePath virtual_path;
if (!FileManagerUtil::ConvertFileToRelativeFileSystemPath(browser->profile(),
dir,
&virtual_path)) {
return;
}
std::string url = chrome::kChromeUIFileManagerURL;
url += '#' + EscapeUrlEncodedData(virtual_path.value(), false);
UserMetrics::RecordAction(UserMetricsAction("ShowFileBrowserFullTab")); UserMetrics::RecordAction(UserMetricsAction("ShowFileBrowserFullTab"));
browser->ShowSingletonTab(GURL(url)); browser->ShowSingletonTab(GURL(url));
} }
...@@ -267,6 +226,53 @@ void FileManagerUtil::ViewItem(const FilePath& full_path, bool enqueue) { ...@@ -267,6 +226,53 @@ void FileManagerUtil::ViewItem(const FilePath& full_path, bool enqueue) {
)); ));
} }
// static
std::string FileManagerUtil::GetArgumentsJson(
SelectFileDialog::Type type,
const string16& title,
const FilePath& default_virtual_path,
const SelectFileDialog::FileTypeInfo* file_types,
int file_type_index,
const FilePath::StringType& default_extension) {
DictionaryValue arg_value;
arg_value.SetString("type", GetDialogTypeAsString(type));
arg_value.SetString("title", title);
// TODO(zelidrag): Convert local system path into virtual path for File API.
arg_value.SetString("defaultPath", default_virtual_path.value());
arg_value.SetString("defaultExtension", default_extension);
if (file_types) {
ListValue* types_list = new ListValue();
for (size_t i = 0; i < file_types->extensions.size(); ++i) {
ListValue* extensions_list = new ListValue();
for (size_t j = 0; j < file_types->extensions[i].size(); ++j) {
extensions_list->Set(
i, Value::CreateStringValue(file_types->extensions[i][j]));
}
DictionaryValue* dict = new DictionaryValue();
dict->Set("extensions", extensions_list);
if (i < file_types->extension_description_overrides.size()) {
string16 desc = file_types->extension_description_overrides[i];
dict->SetString("description", desc);
}
dict->SetBoolean("selected",
(static_cast<size_t>(file_type_index) == i));
types_list->Set(i, dict);
}
arg_value.Set("typeList", types_list);
}
std::string rv;
base::JSONWriter::Write(&arg_value, false, &rv);
return rv;
}
// static // static
std::string FileManagerUtil::GetDialogTypeAsString( std::string FileManagerUtil::GetDialogTypeAsString(
SelectFileDialog::Type dialog_type) { SelectFileDialog::Type dialog_type) {
......
...@@ -42,9 +42,9 @@ class FileManagerUtil { ...@@ -42,9 +42,9 @@ class FileManagerUtil {
const FilePath::StringType& default_extension); const FilePath::StringType& default_extension);
// Opens file browser UI in its own tab on file system location defined with // Opens file browser UI in its own tab on file system location defined with
// |dir|. // |default_path|.
static void ShowFullTabUrl(Profile* profile, static void ShowFullTabUrl(Profile* profile,
const FilePath& dir); const FilePath& default_path);
static void ViewItem(const FilePath& full_path, bool enqueue); static void ViewItem(const FilePath& full_path, bool enqueue);
...@@ -52,6 +52,14 @@ class FileManagerUtil { ...@@ -52,6 +52,14 @@ class FileManagerUtil {
FileManagerUtil() {} FileManagerUtil() {}
// Helper to convert numeric dialog type to a string. // Helper to convert numeric dialog type to a string.
static std::string GetDialogTypeAsString(SelectFileDialog::Type dialog_type); static std::string GetDialogTypeAsString(SelectFileDialog::Type dialog_type);
// Help to convert potential dialog arguments into json.
static std::string GetArgumentsJson(
SelectFileDialog::Type type,
const string16& title,
const FilePath& default_path,
const SelectFileDialog::FileTypeInfo* file_types,
int file_type_index,
const FilePath::StringType& default_extension);
DISALLOW_COPY_AND_ASSIGN(FileManagerUtil); DISALLOW_COPY_AND_ASSIGN(FileManagerUtil);
}; };
......
...@@ -31,15 +31,13 @@ const IMAGE_EDITOR_ENABLED = false; ...@@ -31,15 +31,13 @@ const IMAGE_EDITOR_ENABLED = false;
* - defaultPath: The default path for the dialog. The default path should * - defaultPath: The default path for the dialog. The default path should
* end with a trailing slash if it represents a directory. * end with a trailing slash if it represents a directory.
*/ */
function FileManager(dialogDom, filesystem, rootEntries) { function FileManager(dialogDom, filesystem, rootEntries, params) {
console.log('Init FileManager: ' + dialogDom); console.log('Init FileManager: ' + dialogDom);
this.dialogDom_ = dialogDom; this.dialogDom_ = dialogDom;
this.rootEntries_ = rootEntries; this.rootEntries_ = rootEntries;
this.filesystem_ = filesystem; this.filesystem_ = filesystem;
this.params_ = location.search ? this.params_ = params || {};
JSON.parse(decodeURIComponent(location.search.substr(1))) :
{};
this.listType_ = null; this.listType_ = null;
...@@ -134,7 +132,7 @@ function FileManager(dialogDom, filesystem, rootEntries) { ...@@ -134,7 +132,7 @@ function FileManager(dialogDom, filesystem, rootEntries) {
this.initCommands_(); this.initCommands_();
this.initDom_(); this.initDom_();
this.initDialogType_(); this.initDialogType_();
this.setupCurrentDirectory_(); this.initDefaultDirectory_(this.params_.defaultPath);
this.summarizeSelection_(); this.summarizeSelection_();
this.updatePreview_(); this.updatePreview_();
...@@ -798,7 +796,6 @@ FileManager.prototype = { ...@@ -798,7 +796,6 @@ FileManager.prototype = {
// Rename not in progress. // Rename not in progress.
!this.renameInput_.currentEntry && !this.renameInput_.currentEntry &&
// Only one file selected. // Only one file selected.
this.selection &&
this.selection.totalCount == 1 && this.selection.totalCount == 1 &&
!isSystemDirEntry(this.currentDirEntry_)); !isSystemDirEntry(this.currentDirEntry_));
break; break;
...@@ -1001,11 +998,10 @@ FileManager.prototype = { ...@@ -1001,11 +998,10 @@ FileManager.prototype = {
}; };
/** /**
* Respond to the back and forward buttons. * Respond to the back button.
*/ */
FileManager.prototype.onPopState_ = function(event) { FileManager.prototype.onPopState_ = function(event) {
// TODO(serya): We should restore selected items here. this.changeDirectory(event.state, CD_NO_HISTORY);
this.setupCurrentDirectory_();
}; };
/** /**
...@@ -1038,50 +1034,31 @@ FileManager.prototype = { ...@@ -1038,50 +1034,31 @@ FileManager.prototype = {
errorCallback); errorCallback);
}; };
/** FileManager.prototype.initDefaultDirectory_ = function(path) {
* Restores current directory and may be a selected item after page load (or if (!path) {
* reload) or popping a state (after click on back/forward). If location.hash // No preset given, find a good place to start.
* is present it means that the user has navigated somewhere and that place // Check for removable devices, if there are none, go to Downloads.
* will be restored. defaultPath primarily is used with save/open dialogs. for (var i = 0; i != this.rootEntries_.length; i++) {
* Default path may also contain a file name. Freshly opened file manager var rootEntry = this.rootEntries_[i];
* window has neither. if (rootEntry.fullPath == REMOVABLE_DIRECTORY) {
*/ var foundRemovable = false;
FileManager.prototype.setupCurrentDirectory_ = function() { var self = this;
if (location.hash) { util.forEachDirEntry(rootEntry, function(result) {
// Location hash has the highest priority. if (result) {
var path = decodeURI(location.hash.substr(1)); foundRemovable = true;
this.changeDirectory(path, CD_NO_HISTORY); } else { // Done enumerating, and we know the answer.
return; self.initDefaultDirectory_(
} else if (this.params_.defaultPath) { foundRemovable ? '/' : DOWNLOADS_DIRECTORY);
this.setupPath_(this.params_.defaultPath); }
} else { });
this.setupDefaultPath_(); return;
} }
}; }
FileManager.prototype.setupDefaultPath_ = function() { // Removable root directory is missing altogether.
// No preset given, find a good place to start. path = DOWNLOADS_DIRECTORY;
// Check for removable devices, if there are none, go to Downloads.
var removableDirectoryEntry = this.rootEntries_.filter(function(rootEntry) {
return rootEntry.fullPath == REMOVABLE_DIRECTORY;
})[0];
if (!removableDirectoryEntry) {
this.changeDirectory(DOWNLOADS_DIRECTORY, CD_NO_HISTORY);
return;
} }
var foundRemovable = false;
util.forEachDirEntry(removableDirectoryEntry, function(result) {
if (result) {
foundRemovable = true;
} else { // Done enumerating, and we know the answer.
this.changeDirectory(foundRemovable ? '/' : DOWNLOADS_DIRECTORY,
CD_NO_HISTORY);
}
}.bind(this));
};
FileManager.prototype.setupPath_ = function(path) {
// Split the dirname from the basename. // Split the dirname from the basename.
var ary = path.match(/^(.*?)(?:\/([^\/]+))?$/); var ary = path.match(/^(.*?)(?:\/([^\/]+))?$/);
if (!ary) { if (!ary) {
...@@ -2009,23 +1986,6 @@ FileManager.prototype = { ...@@ -2009,23 +1986,6 @@ FileManager.prototype = {
FileManager.prototype.changeDirectoryEntry = function(dirEntry, FileManager.prototype.changeDirectoryEntry = function(dirEntry,
opt_saveHistory, opt_saveHistory,
opt_selectedEntry) { opt_selectedEntry) {
if (typeof opt_saveHistory == 'undefined') {
opt_saveHistory = true;
} else {
opt_saveHistory = !!opt_saveHistory;
}
var location = '#' + encodeURI(dirEntry.fullPath);
if (opt_saveHistory) {
history.pushState(undefined, dirEntry.fullPath, location);
} else if (window.location.hash != location) {
// If the user typed URL manually that is not canonical it would be fixed
// here. However it seems history.replaceState doesn't work properly
// with rewritable URLs (while does with history.pushState). It changes
// window.location but doesn't change content of the ombibox.
history.replaceState(undefined, dirEntry.fullPath, location);
}
if (this.currentDirEntry_ && if (this.currentDirEntry_ &&
this.currentDirEntry_.fullPath == dirEntry.fullPath) { this.currentDirEntry_.fullPath == dirEntry.fullPath) {
// Directory didn't actually change. // Directory didn't actually change.
...@@ -2034,6 +1994,12 @@ FileManager.prototype = { ...@@ -2034,6 +1994,12 @@ FileManager.prototype = {
return; return;
} }
if (typeof opt_saveHistory == 'undefined') {
opt_saveHistory = true;
} else {
opt_saveHistory = !!opt_saveHistory;
}
var e = new cr.Event('directory-changed'); var e = new cr.Event('directory-changed');
e.previousDirEntry = this.currentDirEntry_; e.previousDirEntry = this.currentDirEntry_;
e.newDirEntry = dirEntry; e.newDirEntry = dirEntry;
...@@ -2060,9 +2026,7 @@ FileManager.prototype = { ...@@ -2060,9 +2026,7 @@ FileManager.prototype = {
opt_saveHistory, opt_saveHistory,
opt_selectedEntry) { opt_selectedEntry) {
if (path == '/') if (path == '/')
return this.changeDirectoryEntry(this.filesystem_.root, return this.changeDirectoryEntry(this.filesystem_.root);
opt_saveHistory,
opt_selectedEntry);
var self = this; var self = this;
...@@ -2074,12 +2038,7 @@ FileManager.prototype = { ...@@ -2074,12 +2038,7 @@ FileManager.prototype = {
}, },
function(err) { function(err) {
console.error('Error changing directory to: ' + path + ', ' + err); console.error('Error changing directory to: ' + path + ', ' + err);
if (self.currentDirEntry_) { if (!self.currentDirEntry_) {
var location = '#' + encodeURI(self.currentDirEntry_.fullPath);
history.replaceState(undefined,
self.currentDirEntry_.fullPath,
location);
} else {
// If we've never successfully changed to a directory, force them // If we've never successfully changed to a directory, force them
// to the root. // to the root.
self.changeDirectory('/', false); self.changeDirectory('/', false);
...@@ -2371,6 +2330,12 @@ FileManager.prototype = { ...@@ -2371,6 +2330,12 @@ FileManager.prototype = {
* @param {cr.Event} event The directory-changed event. * @param {cr.Event} event The directory-changed event.
*/ */
FileManager.prototype.onDirectoryChanged_ = function(event) { FileManager.prototype.onDirectoryChanged_ = function(event) {
if (event.saveHistory) {
history.pushState(this.currentDirEntry_.fullPath,
this.currentDirEntry_.fullPath,
location.href);
}
this.updateCommands_(); this.updateCommands_();
this.updateOkButton_(); this.updateOkButton_();
...@@ -2839,7 +2804,7 @@ FileManager.prototype = { ...@@ -2839,7 +2804,7 @@ FileManager.prototype = {
case 46: // Delete. case 46: // Delete.
if (this.dialogType_ == FileManager.DialogType.FULL_PAGE && if (this.dialogType_ == FileManager.DialogType.FULL_PAGE &&
this.selection && this.selection.totalCount > 0 && this.selection.totalCount > 0 &&
!isSystemDirEntry(this.currentDirEntry_)) { !isSystemDirEntry(this.currentDirEntry_)) {
event.preventDefault(); event.preventDefault();
this.deleteEntries(this.selection.entries); this.deleteEntries(this.selection.entries);
......
...@@ -13,11 +13,19 @@ var fileManager; ...@@ -13,11 +13,19 @@ var fileManager;
* Called by main.html after the dom has been parsed. * Called by main.html after the dom has been parsed.
*/ */
function init() { function init() {
var params;
var rootPaths = ['Downloads', 'removable', 'archive', 'tmp']; var rootPaths = ['Downloads', 'removable', 'archive', 'tmp'];
if (document.location.search) {
var json = decodeURIComponent(document.location.search.substr(1));
var params = JSON.parse(json);
console.log('params: ' + JSON.stringify(params));
}
function onEntriesFound(filesystem, entries) { function onEntriesFound(filesystem, entries) {
FileManager.initStrings(function () { FileManager.initStrings(function () {
fileManager = new FileManager(document.body, filesystem, entries); fileManager = new FileManager(document.body, filesystem, entries, params);
// We're ready to run. Tests can monitor for this state with // We're ready to run. Tests can monitor for this state with
// ExtensionTestMessageListener listener("ready"); // ExtensionTestMessageListener listener("ready");
// ASSERT_TRUE(listener.WaitUntilSatisfied()); // ASSERT_TRUE(listener.WaitUntilSatisfied());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment