Bug 1402550 - Enable saving an .eml file directly. r=mkmelin
- Fix `cmd_saveAsFile` for .eml files that have just been opened from the file system. - Disable `cmd_saveAsTemplate` when such a message is displayed. - When an attached .eml file is opened, try to preserve the filename in the URI (see bug 927640) Based on https://github.com/Betterbird/thunderbird-patches/blob/main/128/bugs/927640-1402550-fix-saving-eml.patch, which is itself based on SeaMonkey code. Differential Revision: https://phabricator.services.mozilla.com/D220719 --HG-- extra : amend_source : 5ffbc0fa2887431b173420fcbc7399ab72b76b55
This commit is contained in:
Родитель
de3bd1b3be
Коммит
3bdd1607d6
|
@ -484,10 +484,33 @@ function SubscribeOKCallback(changeTable) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save as file.
|
||||
*
|
||||
* @param {string[]} uris - URIs of files to save.
|
||||
*/
|
||||
function SaveAsFile(uris) {
|
||||
const filenames = [];
|
||||
|
||||
for (const uri of uris) {
|
||||
// Save an .eml files directly from its URL.
|
||||
if (/type=application\/x-message-display$/.test(uri)) {
|
||||
top.saveURL(
|
||||
uri, // URL
|
||||
null, // originalURL
|
||||
"", // fileName (ignored)
|
||||
null, // filePickerTitleKey
|
||||
true, // shouldBypassCache
|
||||
false, // skipPrompt
|
||||
null, // referrerInfo
|
||||
null, // cookieJarSettings
|
||||
document, // sourceDocument
|
||||
null, // isContentWindowPrivate,
|
||||
Services.scriptSecurityManager.getSystemPrincipal() // principal
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const msgHdr =
|
||||
MailServices.messageServiceFromURI(uri).messageURIToMsgHdr(uri);
|
||||
const nameBase = GenerateFilenameFromMsgHdr(msgHdr);
|
||||
|
|
|
@ -537,8 +537,9 @@ var commandController = {
|
|||
}
|
||||
return false;
|
||||
case "cmd_viewPageSource":
|
||||
case "cmd_saveAsTemplate":
|
||||
return numSelectedMessages == 1;
|
||||
case "cmd_saveAsTemplate":
|
||||
return numSelectedMessages == 1 && !isDummyMessage;
|
||||
case "cmd_reply":
|
||||
case "cmd_replySender":
|
||||
case "cmd_replyall":
|
||||
|
|
|
@ -242,7 +242,16 @@ export class AttachmentInfo {
|
|||
let tempFile = this.#temporaryFiles.get(url);
|
||||
if (!tempFile?.exists()) {
|
||||
tempFile = Services.dirsvc.get("TmpD", Ci.nsIFile);
|
||||
tempFile.append("subPart.eml");
|
||||
// Try to use the name of the attachment for the temporary file, so
|
||||
// that the name is included in the URI of the message that is
|
||||
// opened, and possibly saved as a file later by the user.
|
||||
let sanitizedName = lazy.DownloadPaths.sanitize(this.name);
|
||||
if (!sanitizedName) {
|
||||
sanitizedName = "message.eml";
|
||||
} else if (!/\.eml$/i.test(sanitizedName)) {
|
||||
sanitizedName += ".eml";
|
||||
}
|
||||
tempFile.append(sanitizedName);
|
||||
tempFile.createUnique(0, 0o600);
|
||||
await saveToFile(tempFile.path, true);
|
||||
|
||||
|
|
|
@ -202,6 +202,57 @@ add_task(async function test_forward_eml_catchall() {
|
|||
await BrowserTestUtils.closeWindow(msgc); // close base .eml message
|
||||
});
|
||||
|
||||
/**
|
||||
* Test that saving an .eml opened from a file works.
|
||||
*/
|
||||
add_task(async function test_save_eml_as_file() {
|
||||
const file = new FileUtils.File(getTestFilePath("data/testmsg.eml"));
|
||||
const msgc = await open_message_from_file(file);
|
||||
const pickerPromise = new Promise(resolve => {
|
||||
SpecialPowers.MockFilePicker.init(window.browsingContext);
|
||||
SpecialPowers.MockFilePicker.showCallback = picker => {
|
||||
resolve(picker.defaultString);
|
||||
return Ci.nsIFilePicker.returnOK;
|
||||
};
|
||||
});
|
||||
EventUtils.synthesizeKey("s", { accelKey: true }, msgc);
|
||||
Assert.equal(await pickerPromise, "testmsg.eml");
|
||||
SpecialPowers.MockFilePicker.cleanup();
|
||||
await BrowserTestUtils.closeWindow(msgc);
|
||||
});
|
||||
|
||||
/**
|
||||
* Test that an attached .eml that has been opened retains the correct filename
|
||||
* when it is subsequently saved.
|
||||
*/
|
||||
add_task(async function test_save_eml_as_file() {
|
||||
const file = new FileUtils.File(getTestFilePath("data/testmsg-nested.eml"));
|
||||
const msgc = await open_message_from_file(file);
|
||||
const aboutMessage = get_about_message(msgc);
|
||||
const newWindowPromise = promise_new_window("mail:messageWindow");
|
||||
await EventUtils.synthesizeMouseAtCenter(
|
||||
aboutMessage.document.getElementById("attachmentName"),
|
||||
{},
|
||||
aboutMessage
|
||||
);
|
||||
const msgc2 = await newWindowPromise;
|
||||
const pickerPromise = new Promise(resolve => {
|
||||
SpecialPowers.MockFilePicker.init(window.browsingContext);
|
||||
SpecialPowers.MockFilePicker.showCallback = picker => {
|
||||
resolve(picker.defaultString);
|
||||
return Ci.nsIFilePicker.returnOK;
|
||||
};
|
||||
});
|
||||
EventUtils.synthesizeKey("s", { accelKey: true }, msgc2);
|
||||
Assert.ok(
|
||||
/that's why(-(\d)+)?\.eml/.test(await pickerPromise),
|
||||
"Correct filename"
|
||||
);
|
||||
SpecialPowers.MockFilePicker.cleanup();
|
||||
await BrowserTestUtils.closeWindow(msgc2);
|
||||
await BrowserTestUtils.closeWindow(msgc);
|
||||
});
|
||||
|
||||
/**
|
||||
* Test that clicking on a 'mailto:' link in an .eml opens a compose window.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
Content-Type: multipart/mixed; boundary="------------86SaFvMNv7NcfmcG7KkR6fEI"
|
||||
Message-ID: <69bfee4a-e114-4e84-8c4b-6dc7a983a58a@example.com>
|
||||
Date: Tue, 3 Sep 2024 17:15:35 +0200
|
||||
MIME-Version: 1.0
|
||||
User-Agent: Mozilla Thunderbird
|
||||
From: Marge <marge@example.com>
|
||||
Subject: that's why
|
||||
To: Homer <homer@example.com>
|
||||
Content-Language: en-US
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--------------86SaFvMNv7NcfmcG7KkR6fEI
|
||||
Content-Type: text/plain; charset=UTF-8; format=flowed
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
|
||||
--------------86SaFvMNv7NcfmcG7KkR6fEI
|
||||
Content-Type: message/rfc822; name=that's why.eml"
|
||||
Content-Disposition: attachment; filename="that's why.eml"
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
Return-Path: <homer@example.com>
|
||||
Received: from smtp.example.com (smtpu [10.0.0.52])
|
||||
by storage (Cyrus v2.3.7-Invoca-RPM-2.3.7-1.1) with LMTPA;
|
||||
Mon, 26 Dec 2011 20:49:16 +0200
|
||||
Message-ID: <4EF8C1A5.1060708@example.com>
|
||||
Date: Mon, 26 Dec 2011 20:49:09 +0200
|
||||
From: Homer <homer@example.com>
|
||||
MIME-Version: 1.0
|
||||
To: Marge <marge@example.com>
|
||||
Subject: why
|
||||
Content-Type: text/plain; charset=UTF-8; format=flowed
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
Because they're stupid, that's why. That's why everybody does everything!
|
||||
|
||||
-Homer
|
||||
|
||||
|
||||
--------------86SaFvMNv7NcfmcG7KkR6fEI--
|
Загрузка…
Ссылка в новой задаче