Provide an Mail Extension API to switch between Original HTML | Simple HTML | Plaintext in Message Reader
Categories
(Thunderbird :: Add-Ons: Extensions API, enhancement)
Tracking
(Not tracked)
People
(Reporter: Thunderbird_Mail_DE, Unassigned)
References
Details
(Whiteboard: [Prio2023])
Attachments
(1 file, 7 obsolete files)
12.00 KB,
application/octet-stream
|
Details |
In RFE Bug 1598857 an "Allow HTML Temp" function should be integrated to core Thunderbird. If this RFE will not be implemented into core, it would be necessary to have a relating Mail Extension API, to allow this feature (without manipulating core prefs / about:prefs)
For more information read the description from Bug 1598857
Reporter | ||
Comment 1•4 years ago
|
||
I have to describe that more exactly. It would be necessary to change the related prefs without (!) a reload of the displayed message. After showing the message once in original HTML, the prefs have to be reset to the prior values. The message should "stay" with HTML, but the prefs should be reset.
Comment 2•2 years ago
•
|
||
Edit: Wrong bug. Removed.
Reporter | ||
Comment 3•2 years ago
|
||
If ever such an API is created, one could include an optional parameter that (if true) would then optionally reload the currently displayed message as well.
Comment 4•2 years ago
•
|
||
Do you happen to have code, which I could use to start investigating this?
Edit: I will have a look at your AHT add-on.
Updated•2 years ago
|
Reporter | ||
Comment 5•2 years ago
|
||
Here is my first attemp for the API.
I'm not quite sure, but I think, an onChanged listener could be added. And for a build in API it should require an own permission like "messageContentPolicy".
schema.json:
[
{
"namespace": "messageContentPolicy",
"functions": [
{
"name": "getCurrent",
"description": "Resolves with the object currentPolicy, including the properties msgBodyAs, remoteContent, attachmentsInline",
"type": "function",
"async": true,
"parameters": []
},
{
"name": "update",
"description": "Updates the related application settings by the given updateProperties object, and than reloads the displayed message, if the optional parameter doNotReloadMsg is not true.",
"type": "function",
"async": true,
"parameters": [
{
"name": "windowId",
"type": "integer",
"description": "This windowId is used to get the window in API, to use its global vars and functions."
},
{
"name": "updateProperties",
"type": "object",
"description": "Object with the possible properties msgBodyAs, remoteContent, attachmentsInline. Given properties will be updated.",
"properties": {
"msgBodyAs": {
"type": "string",
"optional": true,
"description": "This message Body mode will be set. Possible values are: plaintext || sanitized || original || allBodyParts"
},
"remoteContent": {
"type": "boolean",
"optional": true,
"description": "If value is true, remote content will be allowed and loaded in displayed messages."
},
"attachmentsInline": {
"type": "boolean",
"optional": true,
"description": "If value is true, attached images will be displayed inline."
}
}
},
{
"name": "doNotReloadMsg",
"type": "boolean",
"optional": true,
"description": "An optional parameter, to suppress message reload after the properties update, if the value = true."
}
]
}
]
}
]
implementation.js
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
var { ExtensionCommon } = ChromeUtils.import("resource://gre/modules/ExtensionCommon.jsm");
var messageContentPolicy = class extends ExtensionCommon.ExtensionAPI {
getAPI(context) {
return {
messageContentPolicy: {
async getCurrent() {
return new Promise(resolve => {
// try {
/* currentPolicy should resolve as an object
currentPolicy.msgBodyAs = plaintext || sanitized || original || allBodyParts
currentPolicy.remoteContent = true || false
currentPolicy.attachmentsInline = true || false
if needed, this could later be extended by other related values
*/
let currentPolicy = {};
let prefer_plaintext = Services.prefs.getBoolPref("mailnews.display.prefer_plaintext");
let html_as = Services.prefs.getIntPref("mailnews.display.html_as");
let disallow_classes = Services.prefs.getIntPref("mailnews.display.disallow_mime_handlers");
if ((prefer_plaintext != true) && (html_as == 0) && (disallow_classes == 0)) {
currentPolicy.msgBodyAs = "original";
}
else if ((prefer_plaintext != true) && (html_as == 3) && (disallow_classes > 0)) {
currentPolicy.msgBodyAs = "sanitized";
}
else if ((prefer_plaintext == true) && (html_as == 1) && (disallow_classes > 0)) {
currentPolicy.msgBodyAs = "plaintext";
}
else if ((prefer_plaintext != true) && (html_as == 4) && (disallow_classes == 0)) {
currentPolicy.msgBodyAs = "allBodyParts";
}
currentPolicy.remoteContent = Services.prefs.getBoolPref("mailnews.message_display.disable_remote_image");
currentPolicy.attachmentsInline = Services.prefs.getBoolPref("mail.inline_attachments");
resolve(currentPolicy);
// } catch (e) { resolve(); }
});
},
async update(windowId, updateProperties, doNotReloadMsg) {
return new Promise(resolve => {
// try {
/* updateProperties must be an object with the following possible properties
updateProperties.msgBodyAs = plaintext || sanitized || original || allBodyParts
updateProperties.remoteContent = true || false
updateProperties.attachmentsInline = true || false
if needed, this could later be extended by other related values
doNotReloadMsg is an optional boolean parameter
if doNotReloadMsg is false or undefined, the message will be reloaded after prefs update (default behaviour)
if doNotReloadMsg is true, than the message must not be reloaded, after prefs update (this is necessary for the "Allow HTML Temp" addon)
*/
/* var gDisallow_classes_no_html is provided as a global var by mailWindowOverlay.js
See comment in: https://searchfox.org/comm-central/source/mail/base/content/mailWindowOverlay.js#69
*/
console.log("updateProperties = ", updateProperties);
let window = context.extension.windowManager.get(windowId).window
let gDisallow_classes_no_html = window.gDisallow_classes_no_html;
console.log("gDisallow_classes_no_html = ", gDisallow_classes_no_html);
// Fallback to default value = 1, if we don't got the global var
if (!gDisallow_classes_no_html) {
gDisallow_classes_no_html = 1;
}
// Update the prefs for HTML mode (Menu View -> Message Body As)
switch(updateProperties.msgBodyAs) {
case "original":
Services.prefs.setBoolPref("mailnews.display.prefer_plaintext", false);
Services.prefs.setIntPref("mailnews.display.html_as", 0);
Services.prefs.setIntPref("mailnews.display.disallow_mime_handlers", 0);
break;
case "sanitized":
Services.prefs.setBoolPref("mailnews.display.prefer_plaintext", false);
Services.prefs.setIntPref("mailnews.display.html_as", 3);
Services.prefs.setIntPref("mailnews.display.disallow_mime_handlers",
gDisallow_classes_no_html);
break;
case "plaintext":
Services.prefs.setBoolPref("mailnews.display.prefer_plaintext", true);
Services.prefs.setIntPref("mailnews.display.html_as", 1);
Services.prefs.setIntPref("mailnews.display.disallow_mime_handlers",
gDisallow_classes_no_html);
break;
case "allBodyParts":
Services.prefs.setBoolPref("mailnews.display.prefer_plaintext", false);
Services.prefs.setIntPref("mailnews.display.html_as", 4);
Services.prefs.setIntPref("mailnews.display.disallow_mime_handlers", 0);
break;
default:
console.log("updateProperties.msgBodyAs is undefined or has an invalid value")
}
// Update the pref for remote content (Preferences → Privacy & Security → Allow remote content in messages)
if (updateProperties.remoteContent === true) {
Services.prefs.setBoolPref("mailnews.message_display.disable_remote_image", true);
}
else if (updateProperties.remoteContent === false) {
Services.prefs.setBoolPref("mailnews.message_display.disable_remote_image", false);
}
else {
console.log("updateProperties.remoteContent is undefined or has an invalid value")
}
// Update the pref for inline attachments (Menu View → Display Attachments Inline)
if (updateProperties.attachmentsInline === true) {
Services.prefs.setBoolPref("mail.inline_attachments", true);
}
else if (updateProperties.attachmentsInline === false) {
Services.prefs.setBoolPref("mail.inline_attachments", false);
}
else {
console.log("updateProperties.attachmentsInline is undefined or has an invalid value");
}
if (doNotReloadMsg) {
resolve(true);
}
// reload message only, if doNotReloadMsg = false or undefined
/* ReloadMessage() is provided by: ************************************************************
https://searchfox.org/comm-central/source/mail/base/content/msgMail3PaneWindow.js#1909
function ReloadMessage() {
if (!gFolderDisplay.selectedMessage) {
return;
}
let view = gFolderDisplay.view.dbView;
if (view) {
view.reloadMessage();
}
}
https://searchfox.org/comm-central/source/mail/base/content/messageWindow.js#949
function ReloadMessage() {
// If the current message was loaded from a file or attachment, so the dbView
// can't handle reloading it. Let's do it ourselves, instead.
if (window.arguments[0] instanceof Ci.nsIURI) {
gMessageDisplay.displayExternalMessage(window.arguments[0].spec);
} else {
gFolderDisplay.view.dbView.reloadMessage();
}
}
******************************************************************************************** */
window.ReloadMessage();
resolve(true);
// } catch (e) { resolve(); }
});
},
}
};
}
};
The try-out-addon will be attached.
Reporter | ||
Comment 6•2 years ago
|
||
Reporter | ||
Comment 7•2 years ago
|
||
Reporter | ||
Comment 8•2 years ago
|
||
Fixed missing semicolons
Reporter | ||
Comment 9•2 years ago
•
|
||
I would build the experiment API into my own addon - at least into a development branch that might end up in a final version for Thunderbird 2023? So we could test the API (with a few helpers from the forum), expand it (onChange listener) and fix problems.
Can you give me feedback on the current status of the API? For example, I need some help with callbacks, since I have no idea how they should look like.
Reporter | ||
Comment 10•2 years ago
|
||
Major logic change for the property "remoteContent", which has been changed to "disableRemoteContent" to better fit the original pref.
Reporter | ||
Comment 11•2 years ago
|
||
Add parameter to get and set hidden allBodyParts menuitem.
This is necessary for addons to know, if they should provide their functions and UI elements for this by default hidden option/menuitem.
Reporter | ||
Comment 12•2 years ago
|
||
Implemented the necessary event
Reporter | ||
Comment 13•2 years ago
|
||
Don't use var - use let instead.
Reporter | ||
Comment 14•2 years ago
|
||
Minor changes to log lines
Comment 15•2 years ago
|
||
Thanks for your contribution. I will look at it soon. I may however implement a different approach, which is not depending on global Prefs at all.
Reporter | ||
Comment 16•2 years ago
•
|
||
Be in mind, that this API should be usable for different Add-ons.
E.g. the "Toggle HTML" addon by Dillinger could use it, to update its button state correctly, when the HTML mode is changed by the user without using the "Toggle HTML" button by his addon. Additionaly Dillingers addon could use the API to know, if the (hidden) allBodyParts option is enabled at all.
The same is for a maybe planned additional addon by me, which could just indicate the HTML mode status in the UI, to be viseble all the time. And this should also be possible, when Thunderbirds own UI was used to change the HTML mode or one of the related "content policy" options. So I have some doubts about your idea and am curious how the approach should/will be.
Updated•2 years ago
|
Updated•9 months ago
|
Description
•