Backout changesets a255a998af6e:9c72d5cfe1fb for bc orange.

This commit is contained in:
Ms2ger 2013-04-01 12:00:49 +02:00
parent c8a93284c0
commit 79841c52f3
10 changed files with 354 additions and 528 deletions

View File

@ -8,51 +8,17 @@ function test() {
waitForExplicitFinish();
requestLongerTimeout(2);
gTests = runTest();
gTests.next();
moveAlong();
}
/*
* ================
* Helper functions
* ================
*/
function moveAlong(aResult) {
function moveAlong() {
try {
gTests.send(aResult);
gTests.next();
} catch (x if x instanceof StopIteration) {
finish();
}
}
function createWindow(aOptions) {
whenNewWindowLoaded(aOptions, function(win) {
moveAlong(win);
});
}
function getFile(downloadLastDir, aURI) {
downloadLastDir.getFileAsync(aURI, function(result) {
moveAlong(result);
});
}
function setFile(downloadLastDir, aURI, aValue) {
downloadLastDir.setFile(aURI, aValue);
executeSoon(moveAlong);
}
function clearHistoryAndWait() {
clearHistory();
executeSoon(function() executeSoon(moveAlong));
}
/*
* ===================
* Function with tests
* ===================
*/
function runTest() {
let FileUtils =
Cu.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils;
@ -74,206 +40,214 @@ function runTest() {
Services.prefs.clearUserPref("browser.download.lastDir.savePerSite");
Services.prefs.clearUserPref("browser.download.lastDir");
[dir1, dir2, dir3].forEach(function(dir) dir.remove(true));
win.close();
pbWin.close();
});
function checkDownloadLastDir(gDownloadLastDir, aLastDir) {
function testOnWindow(aPrivate, aCallback) {
whenNewWindowLoaded({private: aPrivate}, function(win) {
let gDownloadLastDir = new DownloadLastDir(win);
aCallback(win, gDownloadLastDir);
gDownloadLastDir.cleanupPrivateFile();
win.close();
executeSoon(moveAlong);
});
}
function checkInit(aWin, gDownloadLastDir) {
is(typeof gDownloadLastDir, "object",
"gDownloadLastDir should be a valid object");
is(gDownloadLastDir.file, null,
"LastDir pref should be null to start with");
// set up last dir
gDownloadLastDir.setFile(null, tmpDir);
is(gDownloadLastDir.file.path, tmpDir.path,
"LastDir should point to the tmpDir");
isnot(gDownloadLastDir.file, tmpDir,
"gDownloadLastDir.file should not be pointing to tmpDir");
// set uri1 to dir1, all should now return dir1
// also check that a new object is returned
gDownloadLastDir.setFile(uri1, dir1);
is(gDownloadLastDir.file.path, dir1.path,
"gDownloadLastDir should return dir1");
isnot(gDownloadLastDir.file, dir1,
"gDownloadLastDir.file should not return dir1");
is(gDownloadLastDir.getFile(uri1).path, dir1.path,
"uri1 should return dir1"); // set in CPS
isnot(gDownloadLastDir.getFile(uri1), dir1,
"getFile on uri1 should not return dir1");
is(gDownloadLastDir.getFile(uri2).path, dir1.path,
"uri2 should return dir1"); // fallback
isnot(gDownloadLastDir.getFile(uri2), dir1,
"getFile on uri2 should not return dir1");
is(gDownloadLastDir.getFile(uri3).path, dir1.path,
"uri3 should return dir1"); // fallback
isnot(gDownloadLastDir.getFile(uri3), dir1,
"getFile on uri3 should not return dir1");
is(gDownloadLastDir.getFile(uri4).path, dir1.path,
"uri4 should return dir1"); // fallback
isnot(gDownloadLastDir.getFile(uri4), dir1,
"getFile on uri4 should not return dir1");
// set uri2 to dir2, all except uri1 should now return dir2
gDownloadLastDir.setFile(uri2, dir2);
is(gDownloadLastDir.file.path, dir2.path,
"gDownloadLastDir should point to dir2");
is(gDownloadLastDir.getFile(uri1).path, dir1.path,
"uri1 should return dir1"); // set in CPS
is(gDownloadLastDir.getFile(uri2).path, dir2.path,
"uri2 should return dir2"); // set in CPS
is(gDownloadLastDir.getFile(uri3).path, dir2.path,
"uri3 should return dir2"); // fallback
is(gDownloadLastDir.getFile(uri4).path, dir2.path,
"uri4 should return dir2"); // fallback
// set uri3 to dir3, all except uri1 and uri2 should now return dir3
gDownloadLastDir.setFile(uri3, dir3);
is(gDownloadLastDir.file.path, dir3.path,
"gDownloadLastDir should point to dir3");
is(gDownloadLastDir.getFile(uri1).path, dir1.path,
"uri1 should return dir1"); // set in CPS
is(gDownloadLastDir.getFile(uri2).path, dir2.path,
"uri2 should return dir2"); // set in CPS
is(gDownloadLastDir.getFile(uri3).path, dir3.path,
"uri3 should return dir3"); // set in CPS
is(gDownloadLastDir.getFile(uri4).path, dir3.path,
"uri4 should return dir4"); // fallback
// set uri1 to dir2, all except uri3 should now return dir2
gDownloadLastDir.setFile(uri1, dir2);
is(gDownloadLastDir.file.path, dir2.path,
"gDownloadLastDir should point to dir2");
is(gDownloadLastDir.getFile(uri1).path, dir2.path,
"uri1 should return dir2"); // set in CPS
is(gDownloadLastDir.getFile(uri2).path, dir2.path,
"uri2 should return dir2"); // set in CPS
is(gDownloadLastDir.getFile(uri3).path, dir3.path,
"uri3 should return dir3"); // set in CPS
is(gDownloadLastDir.getFile(uri4).path, dir2.path,
"uri4 should return dir2"); // fallback
// check clearHistory removes all data
clearHistory();
is(gDownloadLastDir.file, null, "clearHistory removes all data");
is(Services.contentPrefs.hasPref(uri1, "browser.download.lastDir", null),
false, "LastDir preference should be absent");
is(gDownloadLastDir.getFile(uri1), null, "uri1 should point to null");
is(gDownloadLastDir.getFile(uri2), null, "uri2 should point to null");
is(gDownloadLastDir.getFile(uri3), null, "uri3 should point to null");
is(gDownloadLastDir.getFile(uri4), null, "uri4 should point to null");
}
function checkDownloadLastDir(aWin, gDownloadLastDir, aLastDir) {
is(gDownloadLastDir.file.path, aLastDir.path,
"gDownloadLastDir should point to the expected last directory");
getFile(gDownloadLastDir, uri1);
is(gDownloadLastDir.getFile(uri1).path, aLastDir.path,
"uri1 should return the expected last directory");
}
function checkDownloadLastDirNull(gDownloadLastDir) {
function checkDownloadLastDirNull(aWin, gDownloadLastDir) {
is(gDownloadLastDir.file, null, "gDownloadLastDir should be null");
getFile(gDownloadLastDir, uri1);
is(gDownloadLastDir.getFile(uri1), null, "uri1 should return null");
}
/*
* ================================
* Create a regular and a PB window
* ================================
*/
function checkSetFile(gDownloadLastDir, aDir1, aDir2, aDir3) {
// check that disabling CPS works
Services.prefs.setBoolPref("browser.download.lastDir.savePerSite", false);
let win = yield createWindow({private: false});
let pbWin = yield createWindow({private: true});
gDownloadLastDir.setFile(uri1, aDir1);
is(gDownloadLastDir.file.path, aDir1.path, "LastDir should be set to dir1");
is(gDownloadLastDir.getFile(uri1).path, aDir1.path, "uri1 should return dir1");
is(gDownloadLastDir.getFile(uri2).path, aDir1.path, "uri2 should return dir1");
is(gDownloadLastDir.getFile(uri3).path, aDir1.path, "uri3 should return dir1");
is(gDownloadLastDir.getFile(uri4).path, aDir1.path, "uri4 should return dir1");
let downloadLastDir = new DownloadLastDir(win);
let pbDownloadLastDir = new DownloadLastDir(pbWin);
gDownloadLastDir.setFile(uri2, aDir2);
is(gDownloadLastDir.file.path, aDir2.path, "LastDir should be set to dir2");
is(gDownloadLastDir.getFile(uri1).path, aDir2.path, "uri1 should return dir2");
is(gDownloadLastDir.getFile(uri2).path, aDir2.path, "uri2 should return dir2");
is(gDownloadLastDir.getFile(uri3).path, aDir2.path, "uri3 should return dir2");
is(gDownloadLastDir.getFile(uri4).path, aDir2.path, "uri4 should return dir2");
/*
* ==================
* Beginning of tests
* ==================
*/
Services.prefs.clearUserPref("browser.download.lastDir.savePerSite");
is(typeof downloadLastDir, "object",
"downloadLastDir should be a valid object");
is(downloadLastDir.file, null,
"LastDir pref should be null to start with");
// check that passing null to setFile clears the stored value
gDownloadLastDir.setFile(uri3, aDir3);
is(gDownloadLastDir.getFile(uri3).path, aDir3.path, "LastDir should be set to dir3");
gDownloadLastDir.setFile(uri3, null);
is(gDownloadLastDir.getFile(uri3), null, "uri3 should return null");
}
// set up last dir
yield setFile(downloadLastDir, null, tmpDir);
is(downloadLastDir.file.path, tmpDir.path,
"LastDir should point to the tmpDir");
isnot(downloadLastDir.file, tmpDir,
"downloadLastDir.file should not be pointing to tmpDir");
// set uri1 to dir1, all should now return dir1
// also check that a new object is returned
yield setFile(downloadLastDir, uri1, dir1);
is(downloadLastDir.file.path, dir1.path,
"downloadLastDir should return dir1");
isnot(downloadLastDir.file, dir1,
"downloadLastDir.file should not return dir1");
is((yield getFile(downloadLastDir, uri1)).path, dir1.path,
"uri1 should return dir1"); // set in CPS
isnot((yield getFile(downloadLastDir, uri1)), dir1,
"getFile on uri1 should not return dir1");
is((yield getFile(downloadLastDir, uri2)).path, dir1.path,
"uri2 should return dir1"); // fallback
isnot((yield getFile(downloadLastDir, uri2)), dir1,
"getFile on uri2 should not return dir1");
is((yield getFile(downloadLastDir, uri3)).path, dir1.path,
"uri3 should return dir1"); // fallback
isnot((yield getFile(downloadLastDir, uri3)), dir1,
"getFile on uri3 should not return dir1");
is((yield getFile(downloadLastDir, uri4)).path, dir1.path,
"uri4 should return dir1"); // fallback
isnot((yield getFile(downloadLastDir, uri4)), dir1,
"getFile on uri4 should not return dir1");
// set uri2 to dir2, all except uri1 should now return dir2
yield setFile(downloadLastDir, uri2, dir2);
is(downloadLastDir.file.path, dir2.path,
"downloadLastDir should point to dir2");
is((yield getFile(downloadLastDir, uri1)).path, dir1.path,
"uri1 should return dir1"); // set in CPS
is((yield getFile(downloadLastDir, uri2)).path, dir2.path,
"uri2 should return dir2"); // set in CPS
is((yield getFile(downloadLastDir, uri3)).path, dir2.path,
"uri3 should return dir2"); // fallback
is((yield getFile(downloadLastDir, uri4)).path, dir2.path,
"uri4 should return dir2"); // fallback
// set uri3 to dir3, all except uri1 and uri2 should now return dir3
yield setFile(downloadLastDir, uri3, dir3);
is(downloadLastDir.file.path, dir3.path,
"downloadLastDir should point to dir3");
is((yield getFile(downloadLastDir, uri1)).path, dir1.path,
"uri1 should return dir1"); // set in CPS
is((yield getFile(downloadLastDir, uri2)).path, dir2.path,
"uri2 should return dir2"); // set in CPS
is((yield getFile(downloadLastDir, uri3)).path, dir3.path,
"uri3 should return dir3"); // set in CPS
is((yield getFile(downloadLastDir, uri4)).path, dir3.path,
"uri4 should return dir4"); // fallback
// set uri1 to dir2, all except uri3 should now return dir2
yield setFile(downloadLastDir, uri1, dir2);
is(downloadLastDir.file.path, dir2.path,
"downloadLastDir should point to dir2");
is((yield getFile(downloadLastDir, uri1)).path, dir2.path,
"uri1 should return dir2"); // set in CPS
is((yield getFile(downloadLastDir, uri2)).path, dir2.path,
"uri2 should return dir2"); // set in CPS
is((yield getFile(downloadLastDir, uri3)).path, dir3.path,
"uri3 should return dir3"); // set in CPS
is((yield getFile(downloadLastDir, uri4)).path, dir2.path,
"uri4 should return dir2"); // fallback
yield clearHistoryAndWait();
// check clearHistory removes all data
is(downloadLastDir.file, null, "clearHistory removes all data");
//is(Services.contentPrefs.hasPref(uri1, "browser.download.lastDir", null),
// false, "LastDir preference should be absent");
is((yield getFile(downloadLastDir, uri1)), null, "uri1 should point to null");
is((yield getFile(downloadLastDir, uri2)), null, "uri2 should point to null");
is((yield getFile(downloadLastDir, uri3)), null, "uri3 should point to null");
is((yield getFile(downloadLastDir, uri4)), null, "uri4 should point to null");
yield setFile(downloadLastDir, null, tmpDir);
yield testOnWindow(false, function(win, downloadDir) {
checkInit(win, downloadDir);
downloadDir.setFile(null, tmpDir);
});
// check data set outside PB mode is remembered
is((yield checkDownloadLastDir(pbDownloadLastDir, tmpDir)).path, tmpDir.path, "uri1 should return the expected last directory");
is((yield checkDownloadLastDir(downloadLastDir, tmpDir)).path, tmpDir.path, "uri1 should return the expected last directory");
yield clearHistoryAndWait();
yield setFile(downloadLastDir, uri1, dir1);
yield testOnWindow(true, function(win, downloadDir) {
checkDownloadLastDir(win, downloadDir, tmpDir);
});
yield testOnWindow(false, function(win, downloadDir) {
checkDownloadLastDir(win, downloadDir, tmpDir);
clearHistory();
downloadDir.setFile(uri1, dir1);
});
// check data set using CPS outside PB mode is remembered
is((yield checkDownloadLastDir(pbDownloadLastDir, dir1)).path, dir1.path, "uri1 should return the expected last directory");
is((yield checkDownloadLastDir(downloadLastDir, dir1)).path, dir1.path, "uri1 should return the expected last directory");
yield clearHistoryAndWait();
yield testOnWindow(true, function(win, downloadDir) {
checkDownloadLastDir(win, downloadDir, dir1);
});
yield testOnWindow(false, function(win, downloadDir) {
checkDownloadLastDir(win, downloadDir, dir1);
clearHistory();
});
// check data set inside PB mode is forgotten
yield setFile(pbDownloadLastDir, null, tmpDir);
is((yield checkDownloadLastDir(pbDownloadLastDir, tmpDir)).path, tmpDir.path, "uri1 should return the expected last directory");
is((yield checkDownloadLastDirNull(downloadLastDir)), null, "uri1 should return the expected last directory");
yield clearHistoryAndWait();
yield testOnWindow(true, function(win, downloadDir) {
downloadDir.setFile(null, tmpDir);
checkDownloadLastDir(win, downloadDir, tmpDir);
});
yield testOnWindow(false, function(win, downloadDir) {
checkDownloadLastDirNull(win, downloadDir);
clearHistory();
});
// check data set using CPS inside PB mode is forgotten
yield setFile(pbDownloadLastDir, uri1, dir1);
is((yield checkDownloadLastDir(pbDownloadLastDir, dir1)).path, dir1.path, "uri1 should return the expected last directory");
is((yield checkDownloadLastDirNull(downloadLastDir)), null, "uri1 should return the expected last directory");
yield testOnWindow(true, function(win, downloadDir) {
downloadDir.setFile(uri1, dir1);
checkDownloadLastDir(win, downloadDir, dir1);
});
yield testOnWindow(false, function(win, downloadDir) {
checkDownloadLastDirNull(win, downloadDir);
clearHistory();
downloadDir.setFile(uri1, dir1);
});
// check data set outside PB mode but changed inside is remembered correctly
yield setFile(downloadLastDir, uri1, dir1);
yield setFile(pbDownloadLastDir, uri1, dir2);
is((yield checkDownloadLastDir(pbDownloadLastDir, dir2)).path, dir2.path, "uri1 should return the expected last directory");
is((yield checkDownloadLastDir(downloadLastDir, dir1)).path, dir1.path, "uri1 should return the expected last directory");
yield testOnWindow(true, function(win, downloadDir) {
downloadDir.setFile(uri1, dir2);
checkDownloadLastDir(win, downloadDir, dir2);
});
yield testOnWindow(false, function(win, downloadDir) {
checkDownloadLastDir(win, downloadDir, dir1);
});
/*
* ====================
* Create new PB window
* ====================
*/
// check that the last dir store got cleared in a new PB window
pbWin.close();
let pbWin = yield createWindow({private: true});
let pbDownloadLastDir = new DownloadLastDir(pbWin);
is((yield checkDownloadLastDir(pbDownloadLastDir, dir1)).path, dir1.path, "uri1 should return the expected last directory");
yield clearHistoryAndWait();
// check that the last dir store got cleared
yield testOnWindow(true, function(win, downloadDir) {
checkDownloadLastDir(win, downloadDir, dir1);
});
yield testOnWindow(false, function(win, downloadDir) {
clearHistory();
});
// check clearHistory inside PB mode clears data outside PB mode
yield setFile(pbDownloadLastDir, uri1, dir2);
yield clearHistoryAndWait();
is((yield checkDownloadLastDirNull(downloadLastDir)), null, "uri1 should return the expected last directory");
is((yield checkDownloadLastDirNull(pbDownloadLastDir)), null, "uri1 should return the expected last directory");
// check that disabling CPS works
Services.prefs.setBoolPref("browser.download.lastDir.savePerSite", false);
yield setFile(downloadLastDir, uri1, dir1);
is(downloadLastDir.file.path, dir1.path, "LastDir should be set to dir1");
is((yield getFile(downloadLastDir, uri1)).path, dir1.path, "uri1 should return dir1");
is((yield getFile(downloadLastDir, uri2)).path, dir1.path, "uri2 should return dir1");
is((yield getFile(downloadLastDir, uri3)).path, dir1.path, "uri3 should return dir1");
is((yield getFile(downloadLastDir, uri4)).path, dir1.path, "uri4 should return dir1");
downloadLastDir.setFile(uri2, dir2);
is(downloadLastDir.file.path, dir2.path, "LastDir should be set to dir2");
is((yield getFile(downloadLastDir, uri1)).path, dir2.path, "uri1 should return dir2");
is((yield getFile(downloadLastDir, uri2)).path, dir2.path, "uri2 should return dir2");
is((yield getFile(downloadLastDir, uri3)).path, dir2.path, "uri3 should return dir2");
is((yield getFile(downloadLastDir, uri4)).path, dir2.path, "uri4 should return dir2");
Services.prefs.clearUserPref("browser.download.lastDir.savePerSite");
// check that passing null to setFile clears the stored value
yield setFile(downloadLastDir, uri3, dir3);
is((yield getFile(downloadLastDir, uri3)).path, dir3.path, "LastDir should be set to dir3");
yield setFile(downloadLastDir, uri3, null);
is((yield getFile(downloadLastDir, uri3)), null, "uri3 should return null");
yield clearHistoryAndWait();
yield testOnWindow(true, function(win, downloadDir) {
downloadDir.setFile(uri1, dir2);
clearHistory();
checkDownloadLastDirNull(win, downloadDir);
});
yield testOnWindow(false, function(win, downloadDir) {
checkDownloadLastDirNull(win, downloadDir);
checkSetFile(downloadDir, dir1, dir2, dir3);
});
}

View File

@ -43,6 +43,7 @@ function test() {
let gDownloadLastDir = new DownloadLastDir(win);
aCallback(win, gDownloadLastDir);
gDownloadLastDir.cleanupPrivateFile();
win.close();
});
}
@ -59,25 +60,21 @@ function test() {
MockFilePicker.returnFiles = [aFile];
MockFilePicker.displayDirectory = null;
let file =
launcherDialog.promptForSaveToFile(launcher, context, null, null, null);
ok(!!file, "promptForSaveToFile correctly returned a file");
launcher.saveDestinationAvailable = function (file) {
ok(!!file, "promptForSaveToFile correctly returned a file");
// File picker should start with expected display dir.
is(MockFilePicker.displayDirectory.path, aDisplayDir.path,
"File picker should start with browser.download.lastDir");
// browser.download.lastDir should be modified on not private windows
is(prefs.getComplexValue("lastDir", Ci.nsIFile).path, aLastDir.path,
"LastDir should be the expected last dir");
// gDownloadLastDir should be usable outside of private windows
is(gDownloadLastDir.file.path, aGlobalLastDir.path,
"gDownloadLastDir should be the expected global last dir");
// File picker should start with expected display dir.
is(MockFilePicker.displayDirectory.path, aDisplayDir.path,
"File picker should start with browser.download.lastDir");
// browser.download.lastDir should be modified on not private windows
is(prefs.getComplexValue("lastDir", Ci.nsIFile).path, aLastDir.path,
"LastDir should be the expected last dir");
// gDownloadLastDir should be usable outside of private windows
is(gDownloadLastDir.file.path, aGlobalLastDir.path,
"gDownloadLastDir should be the expected global last dir");
aWin.close();
aCallback();
};
launcherDialog.promptForSaveToFileAsync(launcher, context, null, null, null);
aCallback();
}
testOnWindow(false, function(win, downloadDir) {

View File

@ -66,19 +66,20 @@ function test() {
MockFilePicker.returnFiles = [aFile];
MockFilePicker.displayDirectory = null;
aWin.getTargetFile(params, function() {
// File picker should start with expected display dir.
is(MockFilePicker.displayDirectory.path, aDisplayDir.path,
"File picker should start with browser.download.lastDir");
// browser.download.lastDir should be modified on not private windows
is(prefs.getComplexValue("lastDir", Ci.nsIFile).path, aLastDir.path,
"LastDir should be the expected last dir");
// gDownloadLastDir should be usable outside of private windows
is(gDownloadLastDir.file.path, aGlobalLastDir.path,
"gDownloadLastDir should be the expected global last dir");
ok(aWin.getTargetFile(params),
"Show the file picker dialog with given params");
aCallback();
});
// File picker should start with expected display dir.
is(MockFilePicker.displayDirectory.path, aDisplayDir.path,
"File picker should start with browser.download.lastDir");
// browser.download.lastDir should be modified on not private windows
is(prefs.getComplexValue("lastDir", Ci.nsIFile).path, aLastDir.path,
"LastDir should be the expected last dir");
// gDownloadLastDir should be usable outside of private windows
is(gDownloadLastDir.file.path, aGlobalLastDir.path,
"gDownloadLastDir should be the expected global last dir");
aCallback();
}
testOnWindow(false, function(win, downloadDir) {

View File

@ -286,8 +286,6 @@ function internalSave(aURL, aDocument, aDefaultFileName, aContentDisposition,
file = aChosenData.file;
sourceURI = aChosenData.uri;
saveAsType = kSaveAsType_Complete;
continueSave();
} else {
var charset = null;
if (aDocument)
@ -311,42 +309,38 @@ function internalSave(aURL, aDocument, aDefaultFileName, aContentDisposition,
// Find a URI to use for determining last-downloaded-to directory
let relatedURI = aReferrer || sourceURI;
getTargetFile(fpParams, function(aDialogCancelled) {
if (aDialogCancelled)
return;
if (!getTargetFile(fpParams, aSkipPrompt, relatedURI))
// If the method returned false this is because the user cancelled from
// the save file picker dialog.
return;
saveAsType = fpParams.saveAsType;
file = fpParams.file;
continueSave();
}, aSkipPrompt, relatedURI);
saveAsType = fpParams.saveAsType;
file = fpParams.file;
}
function continueSave() {
// XXX We depend on the following holding true in appendFiltersForContentType():
// If we should save as a complete page, the saveAsType is kSaveAsType_Complete.
// If we should save as text, the saveAsType is kSaveAsType_Text.
var useSaveDocument = aDocument &&
(((saveMode & SAVEMODE_COMPLETE_DOM) && (saveAsType == kSaveAsType_Complete)) ||
((saveMode & SAVEMODE_COMPLETE_TEXT) && (saveAsType == kSaveAsType_Text)));
// If we're saving a document, and are saving either in complete mode or
// as converted text, pass the document to the web browser persist component.
// If we're just saving the HTML (second option in the list), send only the URI.
var persistArgs = {
sourceURI : sourceURI,
sourceReferrer : aReferrer,
sourceDocument : useSaveDocument ? aDocument : null,
targetContentType : (saveAsType == kSaveAsType_Text) ? "text/plain" : null,
targetFile : file,
sourceCacheKey : aCacheKey,
sourcePostData : aDocument ? getPostData(aDocument) : null,
bypassCache : aShouldBypassCache,
initiatingWindow : aInitiatingDocument.defaultView
};
// XXX We depend on the following holding true in appendFiltersForContentType():
// If we should save as a complete page, the saveAsType is kSaveAsType_Complete.
// If we should save as text, the saveAsType is kSaveAsType_Text.
var useSaveDocument = aDocument &&
(((saveMode & SAVEMODE_COMPLETE_DOM) && (saveAsType == kSaveAsType_Complete)) ||
((saveMode & SAVEMODE_COMPLETE_TEXT) && (saveAsType == kSaveAsType_Text)));
// If we're saving a document, and are saving either in complete mode or
// as converted text, pass the document to the web browser persist component.
// If we're just saving the HTML (second option in the list), send only the URI.
var persistArgs = {
sourceURI : sourceURI,
sourceReferrer : aReferrer,
sourceDocument : useSaveDocument ? aDocument : null,
targetContentType : (saveAsType == kSaveAsType_Text) ? "text/plain" : null,
targetFile : file,
sourceCacheKey : aCacheKey,
sourcePostData : aDocument ? getPostData(aDocument) : null,
bypassCache : aShouldBypassCache,
initiatingWindow : aInitiatingDocument.defaultView
};
// Start the actual save process
internalPersist(persistArgs);
}
// Start the actual save process
internalPersist(persistArgs);
}
/**
@ -527,10 +521,6 @@ function initFileInfo(aFI, aURL, aURLCharset, aDocument,
* @param aFpP
* A structure (see definition in internalSave(...) method)
* containing all the data used within this method.
* @param aCallback
* A callback function that will be called once the function finishes.
* The first argument passed to the function will be a boolean that,
* when true, indicated that the user dismissed the file picker.
* @param aSkipPrompt
* If true, attempt to save the file automatically to the user's default
* download directory, thus skipping the explicit prompt for a file name,
@ -542,8 +532,10 @@ function initFileInfo(aFI, aURL, aURLCharset, aDocument,
* An nsIURI associated with the download. The last used
* directory of the picker is retrieved from/stored in the
* Content Pref Service using this URI.
* @return true if the user confirmed a filename in the picker or the picker
* was not displayed; false if they dismissed the picker.
*/
function getTargetFile(aFpP, aCallback, /* optional */ aSkipPrompt, /* optional */ aRelatedURI)
function getTargetFile(aFpP, /* optional */ aSkipPrompt, /* optional */ aRelatedURI)
{
if (!getTargetFile.DownloadLastDir)
Components.utils.import("resource://gre/modules/DownloadLastDir.jsm", getTargetFile);
@ -565,74 +557,66 @@ function getTargetFile(aFpP, aCallback, /* optional */ aSkipPrompt, /* optional
dir.append(getNormalizedLeafName(aFpP.fileInfo.fileName,
aFpP.fileInfo.fileExt));
aFpP.file = uniqueFile(dir);
aCallback(false);
return;
return true;
}
// We must prompt for the file name explicitly.
// If we must prompt because we were asked to...
if (useDownloadDir) {
// Keep async behavior in both branches
Services.tm.mainThread.dispatch(function() {
displayPicker();
}, Components.interfaces.nsIThread.DISPATCH_NORMAL);
} else {
gDownloadLastDir.getFileAsync(aRelatedURI, function getFileAsyncCB(aFile) {
if (aFile.exists()) {
dir = aFile;
dirExists = true;
}
displayPicker();
});
if (!useDownloadDir) try {
// ...find the directory that was last used for saving, and use it in the
// file picker if it is still valid. Otherwise, keep the default of the
// user's default downloads directory. If it doesn't exist, it will be
// changed to the user's desktop later.
var lastDir = gDownloadLastDir.getFile(aRelatedURI);
if (lastDir.exists()) {
dir = lastDir;
dirExists = true;
}
} catch(e) {}
if (!dirExists) {
// Default to desktop.
dir = Services.dirsvc.get("Desk", nsIFile);
}
function displayPicker() {
if (!dirExists) {
// Default to desktop.
dir = Services.dirsvc.get("Desk", nsIFile);
var fp = makeFilePicker();
var titleKey = aFpP.fpTitleKey || "SaveLinkTitle";
fp.init(window, ContentAreaUtils.stringBundle.GetStringFromName(titleKey),
Components.interfaces.nsIFilePicker.modeSave);
fp.displayDirectory = dir;
fp.defaultExtension = aFpP.fileInfo.fileExt;
fp.defaultString = getNormalizedLeafName(aFpP.fileInfo.fileName,
aFpP.fileInfo.fileExt);
appendFiltersForContentType(fp, aFpP.contentType, aFpP.fileInfo.fileExt,
aFpP.saveMode);
// The index of the selected filter is only preserved and restored if there's
// more than one filter in addition to "All Files".
if (aFpP.saveMode != SAVEMODE_FILEONLY) {
try {
fp.filterIndex = prefs.getIntPref("save_converter_index");
}
var fp = makeFilePicker();
var titleKey = aFpP.fpTitleKey || "SaveLinkTitle";
fp.init(window, ContentAreaUtils.stringBundle.GetStringFromName(titleKey),
Components.interfaces.nsIFilePicker.modeSave);
fp.displayDirectory = dir;
fp.defaultExtension = aFpP.fileInfo.fileExt;
fp.defaultString = getNormalizedLeafName(aFpP.fileInfo.fileName,
aFpP.fileInfo.fileExt);
appendFiltersForContentType(fp, aFpP.contentType, aFpP.fileInfo.fileExt,
aFpP.saveMode);
// The index of the selected filter is only preserved and restored if there's
// more than one filter in addition to "All Files".
if (aFpP.saveMode != SAVEMODE_FILEONLY) {
try {
fp.filterIndex = prefs.getIntPref("save_converter_index");
}
catch (e) {
}
catch (e) {
}
if (fp.show() == Components.interfaces.nsIFilePicker.returnCancel || !fp.file) {
aCallback(true);
return;
}
if (aFpP.saveMode != SAVEMODE_FILEONLY)
prefs.setIntPref("save_converter_index", fp.filterIndex);
// Do not store the last save directory as a pref inside the private browsing mode
var directory = fp.file.parent.QueryInterface(nsIFile);
gDownloadLastDir.setFile(aRelatedURI, directory);
fp.file.leafName = validateFileName(fp.file.leafName);
aFpP.saveAsType = fp.filterIndex;
aFpP.file = fp.file;
aFpP.fileURL = fp.fileURL;
aCallback(false);
}
if (fp.show() == Components.interfaces.nsIFilePicker.returnCancel || !fp.file)
return false;
if (aFpP.saveMode != SAVEMODE_FILEONLY)
prefs.setIntPref("save_converter_index", fp.filterIndex);
// Do not store the last save directory as a pref inside the private browsing mode
var directory = fp.file.parent.QueryInterface(nsIFile);
gDownloadLastDir.setFile(aRelatedURI, directory);
fp.file.leafName = validateFileName(fp.file.leafName);
aFpP.saveAsType = fp.filterIndex;
aFpP.file = fp.file;
aFpP.fileURL = fp.fileURL;
return true;
}
// Since we're automatically downloading, we don't get the file picker's

View File

@ -52,11 +52,8 @@ let observer = {
Services.prefs.clearUserPref(LAST_DIR_PREF);
// Ensure that purging session history causes both the session-only PB cache
// and persistent prefs to be cleared.
let cps2 = Components.classes["@mozilla.org/content-pref/service;1"].
getService(Components.interfaces.nsIContentPrefService2);
cps2.removeByName(LAST_DIR_PREF, {usePrivateBrowsing: false});
cps2.removeByName(LAST_DIR_PREF, {usePrivateBrowsing: true});
Services.contentPrefs.removePrefsByName(LAST_DIR_PREF, {usePrivateBrowsing: false});
Services.contentPrefs.removePrefsByName(LAST_DIR_PREF, {usePrivateBrowsing: true});
break;
}
}
@ -101,8 +98,6 @@ DownloadLastDir.prototype = {
cleanupPrivateFile: function () {
gDownloadLastDirFile = null;
},
// This function is now deprecated as it uses the sync nsIContentPrefService
// interface. New consumers should use the getFileAsync function.
getFile: function (aURI) {
if (aURI && isContentPrefEnabled()) {
let loadContext = this.window
@ -128,51 +123,16 @@ DownloadLastDir.prototype = {
else
return readLastDirPref();
},
getFileAsync: function(aURI, aCallback) {
let plainPrefFile = this.getFile();
if (!aURI || !isContentPrefEnabled()) {
Services.tm.mainThread.dispatch(function() aCallback(plainPrefFile),
Components.interfaces.nsIThread.DISPATCH_NORMAL);
return;
}
let uri = aURI instanceof Components.interfaces.nsIURI ? aURI.spec : aURI;
let cps2 = Components.classes["@mozilla.org/content-pref/service;1"]
.getService(Components.interfaces.nsIContentPrefService2);
let loadContext = this.window
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
.QueryInterface(Components.interfaces.nsILoadContext);
let result = null;
cps2.getByDomainAndName(uri, LAST_DIR_PREF, loadContext, {
handleResult: function(aResult) result = aResult,
handleCompletion: function(aReason) {
let file = plainPrefFile;
if (aReason == Components.interfaces.nsIContentPrefCallback2.COMPLETE_OK &&
result instanceof Components.interfaces.nsIContentPref) {
file = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsIFile);
file.initWithPath(result.value);
}
aCallback(file);
}
});
},
setFile: function (aURI, aFile) {
if (aURI && isContentPrefEnabled()) {
let uri = aURI instanceof Components.interfaces.nsIURI ? aURI.spec : aURI;
let cps2 = Components.classes["@mozilla.org/content-pref/service;1"]
.getService(Components.interfaces.nsIContentPrefService2);
let loadContext = this.window
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
.QueryInterface(Components.interfaces.nsILoadContext);
if (aFile instanceof Components.interfaces.nsIFile)
cps2.set(uri, LAST_DIR_PREF, aFile.path, loadContext);
Services.contentPrefs.setPref(aURI, LAST_DIR_PREF, aFile.path, loadContext);
else
cps2.removeByDomainAndName(uri, LAST_DIR_PREF, loadContext);
Services.contentPrefs.removePref(aURI, LAST_DIR_PREF, loadContext);
}
if (this.isPrivate()) {
if (aFile instanceof Components.interfaces.nsIFile)

View File

@ -189,10 +189,6 @@ nsUnknownContentTypeDialog.prototype = {
// Note - this function is called without a dialog, so it cannot access any part
// of the dialog XUL as other functions on this object do.
promptForSaveToFile: function(aLauncher, aContext, aDefaultFile, aSuggestedFileExtension, aForcePrompt) {
throw new Components.Exception("Async version must be used", Components.results.NS_ERROR_NOT_AVAILABLE);
},
promptForSaveToFileAsync: function(aLauncher, aContext, aDefaultFile, aSuggestedFileExtension, aForcePrompt) {
var result = null;
this.mLauncher = aLauncher;
@ -230,16 +226,13 @@ nsUnknownContentTypeDialog.prototype = {
bundle.GetStringFromName("badPermissions.title"),
bundle.GetStringFromName("badPermissions"));
aLauncher.saveDestinationAvailable(null);
return;
}
}
// Check to make sure we have a valid directory, otherwise, prompt
if (result) {
aLauncher.saveDestinationAvailable(result);
return;
}
if (result)
return result;
}
}
@ -279,39 +272,42 @@ nsUnknownContentTypeDialog.prototype = {
.getService(Components.interfaces.nsIDownloadManager);
picker.displayDirectory = dnldMgr.userDownloadsDirectory;
gDownloadLastDir.getFileAsync(aLauncher.source, function LastDirCallback(lastDir) {
if (lastDir && isUsableDirectory(lastDir))
// The last directory preference may not exist, which will throw.
try {
var lastDir = gDownloadLastDir.getFile(aLauncher.source);
if (isUsableDirectory(lastDir))
picker.displayDirectory = lastDir;
}
catch (ex) {
}
if (picker.show() == nsIFilePicker.returnCancel) {
// null result means user cancelled.
aLauncher.saveDestinationAvailable(null);
return;
if (picker.show() == nsIFilePicker.returnCancel) {
// null result means user cancelled.
return null;
}
// Be sure to save the directory the user chose through the Save As...
// dialog as the new browser.download.dir since the old one
// didn't exist.
result = picker.file;
if (result) {
try {
// Remove the file so that it's not there when we ensure non-existence later;
// this is safe because for the file to exist, the user would have had to
// confirm that he wanted the file overwritten.
if (result.exists())
result.remove(false);
}
catch (e) { }
var newDir = result.parent.QueryInterface(Components.interfaces.nsILocalFile);
// Be sure to save the directory the user chose through the Save As...
// dialog as the new browser.download.dir since the old one
// didn't exist.
result = picker.file;
// Do not store the last save directory as a pref inside the private browsing mode
gDownloadLastDir.setFile(aLauncher.source, newDir);
if (result) {
try {
// Remove the file so that it's not there when we ensure non-existence later;
// this is safe because for the file to exist, the user would have had to
// confirm that he wanted the file overwritten.
if (result.exists())
result.remove(false);
}
catch (e) { }
var newDir = result.parent.QueryInterface(Components.interfaces.nsILocalFile);
// Do not store the last save directory as a pref inside the private browsing mode
gDownloadLastDir.setFile(aLauncher.source, newDir);
result = this.validateLeafName(newDir, result.leafName, null);
}
aLauncher.saveDestinationAvailable(result);
}.bind(this));
result = this.validateLeafName(newDir, result.leafName, null);
}
return result;
},
/**

View File

@ -1994,17 +1994,7 @@ nsresult nsExternalAppHandler::CreateProgressListener()
return rv;
}
nsresult nsExternalAppHandler::SaveDestinationAvailable(nsIFile * aFile)
{
if (aFile)
ContinueSave(aFile);
else
Cancel(NS_BINDING_ABORTED);
return NS_OK;
}
void nsExternalAppHandler::RequestSaveDestination(const nsAFlatString &aDefaultFile, const nsAFlatString &aFileExtension)
nsresult nsExternalAppHandler::PromptForSaveToFile(nsIFile ** aNewFile, const nsAFlatString &aDefaultFile, const nsAFlatString &aFileExtension)
{
// invoke the dialog!!!!! use mWindowContext as the window context parameter for the dialog request
// Convert to use file picker? No, then embeddors could not do any sort of
@ -2014,10 +2004,7 @@ void nsExternalAppHandler::RequestSaveDestination(const nsAFlatString &aDefaultF
{
// Get helper app launcher dialog.
mDialog = do_CreateInstance( NS_HELPERAPPLAUNCHERDLG_CONTRACTID, &rv );
if (rv != NS_OK) {
Cancel(NS_BINDING_ABORTED);
return;
}
NS_ENSURE_SUCCESS(rv, rv);
}
// we want to explicitly unescape aDefaultFile b4 passing into the dialog. we can't unescape
@ -2028,25 +2015,14 @@ void nsExternalAppHandler::RequestSaveDestination(const nsAFlatString &aDefaultF
// picker is up would cause Cancel() to be called, and the dialog would be
// released, which would release this object too, which would crash.
// See Bug 249143
nsIFile* fileToUse;
nsRefPtr<nsExternalAppHandler> kungFuDeathGrip(this);
nsCOMPtr<nsIHelperAppLauncherDialog> dlg(mDialog);
rv = mDialog->PromptForSaveToFile(this,
rv = mDialog->PromptForSaveToFile(this,
mWindowContext,
aDefaultFile.get(),
aFileExtension.get(),
mForceSave, &fileToUse);
if (rv == NS_ERROR_NOT_AVAILABLE) {
// we need to use the async version -> nsIHelperAppLauncherDialog.promptForSaveToFileAsync.
rv = mDialog->PromptForSaveToFileAsync(this,
mWindowContext,
aDefaultFile.get(),
aFileExtension.get(),
mForceSave);
} else {
SaveDestinationAvailable(rv == NS_OK ? fileToUse : nullptr);
}
mForceSave, aNewFile);
return rv;
}
nsresult nsExternalAppHandler::MoveFile(nsIFile * aNewFileLocation)
@ -2113,6 +2089,7 @@ nsresult nsExternalAppHandler::MoveFile(nsIFile * aNewFileLocation)
NS_IMETHODIMP nsExternalAppHandler::SaveToDisk(nsIFile * aNewFileLocation, bool aRememberThisPreference)
{
nsresult rv = NS_OK;
if (mCanceled)
return NS_OK;
@ -2121,9 +2098,11 @@ NS_IMETHODIMP nsExternalAppHandler::SaveToDisk(nsIFile * aNewFileLocation, bool
// The helper app dialog has told us what to do.
mReceivedDispositionInfo = true;
if (!aNewFileLocation) {
nsCOMPtr<nsIFile> fileToUse = do_QueryInterface(aNewFileLocation);
if (!fileToUse)
{
if (mSuggestedFileName.IsEmpty())
RequestSaveDestination(mTempLeafName, mTempFileExtension);
rv = PromptForSaveToFile(getter_AddRefs(fileToUse), mTempLeafName, mTempFileExtension);
else
{
nsAutoString fileExt;
@ -2133,20 +2112,15 @@ NS_IMETHODIMP nsExternalAppHandler::SaveToDisk(nsIFile * aNewFileLocation, bool
if (fileExt.IsEmpty())
fileExt = mTempFileExtension;
RequestSaveDestination(mSuggestedFileName, fileExt);
rv = PromptForSaveToFile(getter_AddRefs(fileToUse), mSuggestedFileName, fileExt);
}
if (NS_FAILED(rv) || !fileToUse) {
Cancel(NS_BINDING_ABORTED);
return NS_ERROR_FAILURE;
}
} else {
ContinueSave(aNewFileLocation);
}
return NS_OK;
}
nsresult nsExternalAppHandler::ContinueSave(nsIFile * aNewFileLocation)
{
NS_PRECONDITION(aNewFileLocation, "Must be called with a non-null file");
nsresult rv = NS_OK;
nsCOMPtr<nsIFile> fileToUse = do_QueryInterface(aNewFileLocation);
mFinalFileDestination = do_QueryInterface(fileToUse);
// Move what we have in the final directory, but append .part

View File

@ -342,34 +342,9 @@ protected:
* what's going on...
*/
nsresult CreateProgressListener();
/*
* The following two functions are part of the split of SaveToDisk
* to make it async, and works as following:
*
* SaveToDisk -------> RequestSaveDestination
* .
* .
* v
* ContinueSave <------- SaveDestinationAvailable
*/
/**
* This is called by SaveToDisk to decide what's the final
* file destination chosen by the user or by auto-download settings.
*/
void RequestSaveDestination(const nsAFlatString &aDefaultFile,
const nsAFlatString &aDefaultFileExt);
/**
* When SaveToDisk is called, it possibly delegates to RequestSaveDestination
* to decide the file destination. ContinueSave must then be called when
* the final destination is finally known.
* @param aFile The file that was chosen as the final destination.
* Must not be null.
*/
nsresult ContinueSave(nsIFile* aFile);
nsresult PromptForSaveToFile(nsIFile ** aNewFile,
const nsAFlatString &aDefaultFile,
const nsAFlatString &aDefaultFileExt);
/**
* After we're done prompting the user for any information, if the original

View File

@ -76,7 +76,7 @@ interface nsPIExternalAppLauncher : nsISupports
* Note that cancelling the load via the nsICancelable interface will release
* the reference to the launcher dialog.
*/
[scriptable, uuid(acf2a516-7d7f-4771-8b22-6c4a559c088e)]
[scriptable, uuid(d9a19faf-497b-408c-b995-777d956b72c0)]
interface nsIHelperAppLauncher : nsICancelable
{
/**
@ -110,13 +110,6 @@ interface nsIHelperAppLauncher : nsICancelable
*/
void launchWithApplication(in nsIFile aApplication, in boolean aRememberThisPreference);
/**
* Callback invoked by nsIHelperAppLauncherDialog::promptForSaveToFileAsync
* after the user has chosen a file through the File Picker (or dismissed it).
* @param aFile The file that was chosen by the user (or null if dialog was dismissed).
*/
void saveDestinationAvailable(in nsIFile aFile);
/**
* The following methods are used by the progress dialog to get or set
* information on the current helper app launcher download.

View File

@ -21,7 +21,7 @@ interface nsIFile;
* will access methods of the nsIHelperAppLauncher passed in to show()
* in order to cause a "save to disk" or "open using" action.
*/
[scriptable, uuid(3ae4dca8-ac91-4891-adcf-3fbebed6170e)]
[scriptable, uuid(f3704fdc-8ae6-4eba-a3c3-f02958ac0649)]
interface nsIHelperAppLauncherDialog : nsISupports {
/**
* This request is passed to the helper app dialog because Gecko can not
@ -73,40 +73,12 @@ interface nsIHelperAppLauncherDialog : nsISupports {
* Set to true to force prompting the user for thet file
* name/location, otherwise perferences may control if the user is
* prompted.
*
* @throws NS_ERROR_NOT_AVAILABLE if the async version of this function
* should be used.
*/
nsIFile promptForSaveToFile(in nsIHelperAppLauncher aLauncher,
in nsISupports aWindowContext,
in wstring aDefaultFileName,
in wstring aSuggestedFileExtension,
in boolean aForcePrompt);
/**
* Async invoke a save-to-file dialog instead of the full fledged helper app
* dialog. When the file is chosen (or the dialog is closed), the callback
* in aLauncher (aLauncher.saveDestinationAvailable) is called with the
* selected file.
*
* @param aLauncher
* A nsIHelperAppLauncher to be invoked when a file is selected.
* @param aWindowContext
* Window associated with action.
* @param aDefaultFileName
* Default file name to provide (can be null)
* @param aSuggestedFileExtension
* Sugested file extension
* @param aForcePrompt
* Set to true to force prompting the user for thet file
* name/location, otherwise perferences may control if the user is
* prompted.
*/
void promptForSaveToFileAsync(in nsIHelperAppLauncher aLauncher,
in nsISupports aWindowContext,
in wstring aDefaultFileName,
in wstring aSuggestedFileExtension,
in boolean aForcePrompt);
};