From 1a9b300cbb6c7bd91c392f35a1eaadf811c5ec10 Mon Sep 17 00:00:00 2001 From: Tomislav Jovanovic Date: Thu, 29 Mar 2018 20:09:45 +0200 Subject: [PATCH] Bug 1418616 - Add default extension to downloads saveAs dialogs, r=rpl MozReview-Commit-ID: 9WOfZoc7wa6 --HG-- extra : rebase_source : c9c91002be76f37dc80132f92e9b11e11f4ab4e9 --- toolkit/components/extensions/parent/ext-downloads.js | 10 ++++++++-- .../test/mochitest/test_chrome_ext_downloads_saveAs.html | 15 ++++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/toolkit/components/extensions/parent/ext-downloads.js b/toolkit/components/extensions/parent/ext-downloads.js index 2d9cf20bd0a2..a08d089e7808 100644 --- a/toolkit/components/extensions/parent/ext-downloads.js +++ b/toolkit/components/extensions/parent/ext-downloads.js @@ -519,13 +519,19 @@ this.downloads = class extends ExtensionAPI { return target; } + const window = Services.wm.getMostRecentWindow("navigator:browser"); + const basename = OS.Path.basename(target); + const ext = basename.match(/\.([^.]+)$/); + // Setup the file picker Save As dialog. const picker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); - const window = Services.wm.getMostRecentWindow("navigator:browser"); picker.init(window, null, Ci.nsIFilePicker.modeSave); picker.displayDirectory = new FileUtils.File(dir); picker.appendFilters(Ci.nsIFilePicker.filterAll); - picker.defaultString = OS.Path.basename(target); + picker.defaultString = basename; + + // Configure a default file extension, used as fallback on Windows. + picker.defaultExtension = ext && ext[1]; // Open the dialog and resolve/reject with the result. return new Promise((resolve, reject) => { diff --git a/toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_saveAs.html b/toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_saveAs.html index d583bb698fdd..5bee14695c6b 100644 --- a/toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_saveAs.html +++ b/toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_saveAs.html @@ -49,10 +49,10 @@ add_task(async function setup() { add_task(async function test_downloads_saveAs() { const pickerFile = pickerDir.clone(); - pickerFile.append("file_download.txt"); + pickerFile.append("file_download.nonext.txt"); const defaultFile = defaultDir.clone(); - defaultFile.append("file_download.txt"); + defaultFile.append("file_download.nonext.txt"); const {MockFilePicker} = SpecialPowers; MockFilePicker.init(window); @@ -61,6 +61,11 @@ add_task(async function test_downloads_saveAs() { // On picker 'show' event, choose the filename that was set as the default // and append it to the picker's download directory let file = pickerDir.clone(); + + // Assert that the downloads API configures both default properties. + is(fp.defaultString, "file_download.nonext.txt", "Got the expected FilePicker defaultString"); + is(fp.defaultExtension, "txt", "Got the expected FilePicker defaultExtension"); + file.append(fp.defaultString); MockFilePicker.setFiles([file]); }; @@ -101,7 +106,7 @@ add_task(async function test_downloads_saveAs() { MockFilePicker.returnValue = MockFilePicker.returnOK; - extension.sendMessage("file_download.txt", saveAs); + extension.sendMessage("file_download.nonext.txt", saveAs); let result = await extension.awaitMessage("done"); ok(result.ok, `downloads.download() works with saveAs=${saveAs}`); @@ -112,7 +117,7 @@ add_task(async function test_downloads_saveAs() { // Test the user canceling the save dialog. MockFilePicker.returnValue = MockFilePicker.returnCancel; - extension.sendMessage("file_download.txt", saveAs); + extension.sendMessage("file_download.nonext.txt", saveAs); result = await extension.awaitMessage("done"); ok(!result.ok, "download rejected if the user cancels the dialog"); @@ -123,7 +128,7 @@ add_task(async function test_downloads_saveAs() { async function testNoFilePicker(saveAs) { ok(!defaultFile.exists(), "the file should have been cleaned up properly previously"); - extension.sendMessage("file_download.txt", saveAs); + extension.sendMessage("file_download.nonext.txt", saveAs); let result = await extension.awaitMessage("done"); ok(result.ok, `downloads.download() works with saveAs=${saveAs}`); -- 2.11.4.GIT