Bug 1357846 - Introducing nsIFilePicker.displaySpecialDirectory, r=smaug

nsIFilePicker.displaySpecialDirectory is a string that can be set to TmpD,
Desk, or any other special directory value. The real value of this directory
will be read in the parent process.
This commit is contained in:
Andrea Marchesini 2017-04-26 18:20:19 +02:00
Родитель 1f7f29a517
Коммит 8beb8af7d4
15 изменённых файлов: 131 добавлений и 28 удалений

Просмотреть файл

@ -429,24 +429,29 @@ UploadLastDir::ContentPrefCallback::HandleCompletion(uint16_t aReason)
if (aReason == nsIContentPrefCallback2::COMPLETE_ERROR || !mResult) {
prefStr = Preferences::GetString("dom.input.fallbackUploadDir");
if (prefStr.IsEmpty()) {
// If no custom directory was set through the pref, default to
// "desktop" directory for each platform.
NS_GetSpecialDirectory(NS_OS_DESKTOP_DIR, getter_AddRefs(localFile));
}
}
if (!localFile) {
if (prefStr.IsEmpty() && mResult) {
nsCOMPtr<nsIVariant> pref;
mResult->GetValue(getter_AddRefs(pref));
pref->GetAsAString(prefStr);
}
if (prefStr.IsEmpty() && mResult) {
nsCOMPtr<nsIVariant> pref;
mResult->GetValue(getter_AddRefs(pref));
pref->GetAsAString(prefStr);
}
if (!prefStr.IsEmpty()) {
localFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
localFile->InitWithPath(prefStr);
if (localFile && NS_WARN_IF(NS_FAILED(localFile->InitWithPath(prefStr)))) {
localFile = nullptr;
}
}
if (localFile) {
mFilePicker->SetDisplayDirectory(localFile);
} else {
// If no custom directory was set through the pref, default to
// "desktop" directory for each platform.
mFilePicker->SetDisplaySpecialDirectory(NS_LITERAL_STRING(NS_OS_DESKTOP_DIR));
}
mFilePicker->SetDisplayDirectory(localFile);
mFilePicker->Open(mFpCallback);
return NS_OK;
}

Просмотреть файл

@ -47,15 +47,18 @@ f.focus();
var testIndex = 0;
var tests = [
["", defaultUploadDirectory.path],
[customUploadDirectory.path, customUploadDirectory.path]
["", null, "Desk"],
[customUploadDirectory.path, customUploadDirectory.path, ""]
]
MockFilePicker.showCallback = function(filepicker) {
info(SpecialPowers.wrap(MockFilePicker).displayDirectory.path);
if (tests[testIndex][1] === null) {
is(SpecialPowers.wrap(MockFilePicker).displayDirectory, null, "DisplayDirectory is null");
} else {
is(SpecialPowers.wrap(MockFilePicker).displayDirectory.path, tests[testIndex][1], "DisplayDirectory matches the path");
}
is(SpecialPowers.wrap(MockFilePicker).displayDirectory.path,
tests[testIndex][1]);
is(SpecialPowers.wrap(MockFilePicker).displaySpecialDirectory, tests[testIndex][2], "DisplaySpecialDirectory matches the path");
if (++testIndex == tests.length) {
MockFilePicker.cleanup();

Просмотреть файл

@ -260,6 +260,7 @@ FilePickerParent::RecvOpen(const int16_t& aSelectedType,
InfallibleTArray<nsString>&& aFilters,
InfallibleTArray<nsString>&& aFilterNames,
const nsString& aDisplayDirectory,
const nsString& aDisplaySpecialDirectory,
const nsString& aOkButtonLabel)
{
if (!CreateFilePicker()) {
@ -284,6 +285,8 @@ FilePickerParent::RecvOpen(const int16_t& aSelectedType,
localFile->InitWithPath(aDisplayDirectory);
mFilePicker->SetDisplayDirectory(localFile);
}
} else if (!aDisplaySpecialDirectory.IsEmpty()) {
mFilePicker->SetDisplaySpecialDirectory(aDisplaySpecialDirectory);
}
mCallback = new FilePickerShownCallback(this);

Просмотреть файл

@ -52,6 +52,7 @@ class FilePickerParent : public PFilePickerParent
InfallibleTArray<nsString>&& aFilters,
InfallibleTArray<nsString>&& aFilterNames,
const nsString& aDisplayDirectory,
const nsString& aDisplaySpecialDirectory,
const nsString& aOkButtonLabel) override;
virtual void ActorDestroy(ActorDestroyReason aWhy) override;

Просмотреть файл

@ -41,7 +41,8 @@ protocol PFilePicker
parent:
async Open(int16_t selectedType, bool addToRecentDocs, nsString defaultFile,
nsString defaultExtension, nsString[] filters, nsString[] filterNames,
nsString displayDirectory, nsString okButtonLabel);
nsString displayDirectory, nsString displaySpecialDirectory,
nsString okButtonLabel);
child:
async __delete__(MaybeInputData data, int16_t result);

Просмотреть файл

@ -170,7 +170,10 @@ MockFilePicker.showCallback = function(filepicker) {
var test = tests[testIndex];
var returned = -1;
for (var i = 0; i < dirs.length; i++) {
if (dirs[i].path == MockFilePicker.displayDirectory.path) {
var dir = MockFilePicker.displayDirectory
? MockFilePicker.displayDirectory
: Services.dirsvc.get(MockFilePicker.displaySpecialDirectory, Ci.nsILocalFile);
if (dirs[i].path == dir.path) {
returned = i;
break;
}

Просмотреть файл

@ -24,6 +24,7 @@ FilePicker.prototype = {
_domFile: null,
_defaultExtension: null,
_displayDirectory: null,
_displaySpecialDirectory: null,
_filePath: null,
_promptActive: false,
_filterIndex: 0,
@ -122,6 +123,14 @@ FilePicker.prototype = {
this._displayDirectory = dir;
},
get displaySpecialDirectory() {
return this._displaySpecialDirectory;
},
set displaySpecialDirectory(dir) {
this._displaySpecialDirectory = dir;
},
get file() {
if (!this._filePath) {
return null;

Просмотреть файл

@ -1017,6 +1017,13 @@ FilePickerDelegate.prototype = {
set displayDirectory(aValue) {
},
get displaySpecialDirectory() {
return "";
},
set displaySpecialDirectory(aValue) {
},
get addToRecentDocs() {
return false;
},

Просмотреть файл

@ -72,6 +72,7 @@ this.MockFilePicker = {
this.appendFilterCallback = null;
this.appendFiltersCallback = null;
this.displayDirectory = null;
this.displaySpecialDirectory = "";
this.filterIndex = 0;
this.mode = null;
this.returnData = [];
@ -179,6 +180,7 @@ MockFilePickerInstance.prototype = {
parent: null,
filterIndex: 0,
displayDirectory: null,
displaySpecialDirectory: "",
get file() {
if (MockFilePicker.returnData.length >= 1) {
return MockFilePicker.returnData[0].nsIFile;
@ -269,6 +271,7 @@ MockFilePickerInstance.prototype = {
}
MockFilePicker.displayDirectory = this.displayDirectory;
MockFilePicker.displaySpecialDirectory = this.displaySpecialDirectory;
MockFilePicker.shown = true;
if (typeof MockFilePicker.showCallback == "function") {
try {

Просмотреть файл

@ -47,6 +47,7 @@ function filepickerLoad() {
if (o.displayDirectory) {
var directory = o.displayDirectory.path;
}
var specialDirectory = o.displaySpecialDirectory;
const initialText = o.defaultString;
var filterTitles = o.filters.titles;
@ -133,21 +134,23 @@ function filepickerLoad() {
// This allows the window to show onscreen before we begin
// loading the file list
setTimeout(setInitialDirectory, 0, directory);
setTimeout(setInitialDirectory, 0, { directory, specialDirectory });
}
function setInitialDirectory(directory) {
function setInitialDirectory(directories) {
// Start in the user's home directory
var dirService = Components.classes[NS_DIRECTORYSERVICE_CONTRACTID]
.getService(nsIProperties);
homeDir = dirService.get("Home", Components.interfaces.nsIFile);
homeDir = dirService.get(directories.specialDirectory
? directories.specialDirectory : "Home",
Components.interfaces.nsIFile);
if (directory) {
sfile.initWithPath(directory);
if (directories.directory) {
sfile.initWithPath(directories.directory);
if (!sfile.exists() || !sfile.isDirectory())
directory = false;
directories.directory = false;
}
if (!directory) {
if (!directories.directory) {
sfile.initWithPath(homeDir.path);
}

Просмотреть файл

@ -55,6 +55,7 @@ function nsFilePicker() {
this.mFilterTitles = new Array();
this.mFilters = new Array();
this.mDisplayDirectory = null;
this.mDisplaySpecialDirectory = null;
if (lastDirectory) {
try {
var dir = Components.classes[LOCAL_FILE_CONTRACTID].createInstance(nsILocalFile);
@ -87,6 +88,14 @@ nsFilePicker.prototype = {
.QueryInterface(nsILocalFile);
},
/* attribute AString displaySpecialDirectory; */
set displaySpecialDirectory(a) {
this.mDisplaySpecialDirectory = a;
},
get displaySpecialDirectory() {
return this.mDisplaySpecialDirectory;
},
/* readonly attribute nsILocalFile file; */
get file() { return this.mFilesEnumerator.mFiles[0]; },
@ -256,6 +265,7 @@ nsFilePicker.prototype = {
o.title = this.mTitle;
o.mode = this.mMode;
o.displayDirectory = this.mDisplayDirectory;
o.displaySpecialDirectory = this.mDisplaySpecialDirectory;
o.defaultString = this.mDefaultString;
o.filterIndex = this.mFilterIndex;
o.filters = {};

Просмотреть файл

@ -295,6 +295,12 @@ NS_IMETHODIMP nsBaseFilePicker::GetFiles(nsISimpleEnumerator **aFiles)
// Set the display directory
NS_IMETHODIMP nsBaseFilePicker::SetDisplayDirectory(nsIFile *aDirectory)
{
// if displaySpecialDirectory has been previously called, let's abort this
// operation.
if (!mDisplaySpecialDirectory.IsEmpty()) {
return NS_OK;
}
if (!aDirectory) {
mDisplayDirectory = nullptr;
return NS_OK;
@ -311,6 +317,13 @@ NS_IMETHODIMP nsBaseFilePicker::SetDisplayDirectory(nsIFile *aDirectory)
NS_IMETHODIMP nsBaseFilePicker::GetDisplayDirectory(nsIFile **aDirectory)
{
*aDirectory = nullptr;
// if displaySpecialDirectory has been previously called, let's abort this
// operation.
if (!mDisplaySpecialDirectory.IsEmpty()) {
return NS_OK;
}
if (!mDisplayDirectory)
return NS_OK;
nsCOMPtr<nsIFile> directory;
@ -322,6 +335,31 @@ NS_IMETHODIMP nsBaseFilePicker::GetDisplayDirectory(nsIFile **aDirectory)
return NS_OK;
}
// Set the display special directory
NS_IMETHODIMP nsBaseFilePicker::SetDisplaySpecialDirectory(const nsAString& aDirectory)
{
// if displayDirectory has been previously called, let's abort this operation.
if (mDisplayDirectory && mDisplaySpecialDirectory.IsEmpty()) {
return NS_OK;
}
mDisplaySpecialDirectory = aDirectory;
if (mDisplaySpecialDirectory.IsEmpty()) {
mDisplayDirectory = nullptr;
return NS_OK;
}
return NS_GetSpecialDirectory(NS_ConvertUTF16toUTF8(mDisplaySpecialDirectory).get(),
getter_AddRefs(mDisplayDirectory));
}
// Get the display special directory
NS_IMETHODIMP nsBaseFilePicker::GetDisplaySpecialDirectory(nsAString& aDirectory)
{
aDirectory = mDisplaySpecialDirectory;
return NS_OK;
}
NS_IMETHODIMP
nsBaseFilePicker::GetAddToRecentDocs(bool *aFlag)
{

Просмотреть файл

@ -34,6 +34,8 @@ public:
NS_IMETHOD GetFiles(nsISimpleEnumerator **aFiles);
NS_IMETHOD GetDisplayDirectory(nsIFile * *aDisplayDirectory);
NS_IMETHOD SetDisplayDirectory(nsIFile * aDisplayDirectory);
NS_IMETHOD GetDisplaySpecialDirectory(nsAString& aDisplayDirectory);
NS_IMETHOD SetDisplaySpecialDirectory(const nsAString& aDisplayDirectory);
NS_IMETHOD GetAddToRecentDocs(bool *aFlag);
NS_IMETHOD SetAddToRecentDocs(bool aFlag);
NS_IMETHOD GetMode(int16_t *aMode);
@ -49,6 +51,7 @@ protected:
bool mAddToRecentDocs;
nsCOMPtr<nsIFile> mDisplayDirectory;
nsString mDisplaySpecialDirectory;
nsCOMPtr<nsPIDOMWindowOuter> mParent;
int16_t mMode;

Просмотреть файл

@ -144,7 +144,8 @@ nsFilePickerProxy::Open(nsIFilePickerShownCallback* aCallback)
}
SendOpen(mSelectedType, mAddToRecentDocs, mDefault, mDefaultExtension,
mFilters, mFilterNames, displayDirectory, mOkButtonLabel);
mFilters, mFilterNames, displayDirectory, mDisplaySpecialDirectory,
mOkButtonLabel);
return NS_OK;
}

Просмотреть файл

@ -112,12 +112,25 @@ interface nsIFilePicker : nsISupports
/**
* Set the directory that the file open/save dialog initially displays
* Note that, if displaySpecialDirectory has been already set, this value will
* be ignored.
*
* @param displayDirectory the name of the directory
*
*/
attribute nsIFile displayDirectory;
/**
* Set the directory that the file open/save dialog initially displays using
* one of the special name as such as 'Desk', 'TmpD', and so on.
* Note that, if displayDirectory has been already set, this value will be
* ignored.
*
* @param displaySpecialDirectory the name of the special directory
*
*/
attribute AString displaySpecialDirectory;
/**
* Get the nsIFile for the file or directory.