Skip to content

Commit

Permalink
Add an option to also process existing images when using Forward/Repl…
Browse files Browse the repository at this point in the history
…y to

- Added option to also resize images from the original e-mail when using forward / reply (#15). This feature also works with autoresize.
- Fixed wrong variable name in content_script.js, that caused the log to console option to always be disabled.
- Added a simple "How to use" section to readme.
  • Loading branch information
memeller committed Mar 5, 2024
1 parent af1d4de commit 20e35b9
Show file tree
Hide file tree
Showing 14 changed files with 115 additions and 37 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## v5.8.0

- Added option to also resize images from the original e-mail when using forward / reply (#15). This feature also works with autoresize.\
- Fixed wrong variable name in content_script.js, that caused the log to console option to always be disabled.
- Added a simple "How to use" section to readme.

## v5.7.2

- Fixed - the image is not resized when right clicking inline image, selecting resize image and clicking ok. (#23)\
Expand Down
28 changes: 21 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,28 @@ Since the original repo is no longer mantained and became read-only on 28th of D

Each time a compatible (JPG/PNG/BMP) image is attached to/inserted into new e-mail the user has the ability to resize the image. The resized image replaces previously inserted / attached one.

## Installation

Head over to [release page](https://github.com/memeller/shrunked/releases/latest) and download the xpi. \
If you are using Firefox, you will need to right click on the link and select "Save link as...", otherwise Firefox will try to install the xpi file in Firefox.\
Open Thunderbird, open Add-ons (Tools -> Add-ons and Themes), select "Install Add-on From File..."\
![install from file](/images/install_from_file.png)\
and select the downloaded xpi.

## How to use

After installing the add-on, some options are set by default. Please adjust the options if, for example, you want images to be resized in reply/forward mode.\
![png options](/images/options.png)\
Each time you attach/insert an image into an email, a small notfication will appear asking if you would like to resize the image(s).\
![png options](/images/notification.png)\
If you select 'Yes', a small window will appear allowing you to set the target dimensions, see the size of the image before and after, etc.\
![png options](/images/popup.png)\
After confirming the resize, the attachments / inline images will be replaced with their resized versions.\

## New in this fork (vs darkrojan's version):

- Added Autoresize (currently works only for newly added attachments / inline images). This can be enabled for all images / inline only / attachments only. When enabled, each time an image is inserted / attached, the requirements for the resize function are checked (file size / dimensions, the ones set in options panel). If the image should be resized, it will be resized and replaced automatically, without any user interaction.
- Added support for resizing images when forwarding / replying to messages. This can be enabled in the options, disabled by default.
- Added Autoresize. This can be enabled for all images / inline only / attachments only. When enabled, each time an image is inserted / attached, the requirements for the resize function are checked (file size / dimensions, the ones set in options panel). If the image should be resized, it will be resized and replaced automatically, without any user interaction.
- Added PL lang support,
- BMP support (converted to JPG when resized),
- PNG support,
Expand All @@ -28,11 +47,6 @@ It is used by default, to use the previous algorithm please uncheck the correspo
- If the selected file cannot be resized, the context menu item is disabled and shows additional information instead of item being hidden.
- Console logging can be disabled.

## Installation
Head over to [release page](https://github.com/memeller/shrunked/releases/latest) and download the xpi. \
If you are using Firefox you need to right click the link and select "Save link as...", otherwise Firefox will try to install the xpi file in Firefox.\
Open Thunderbird, open Add-ons (Tools -> Add-ons and Themes), select "Install Add-on From File..."\
![install from file](/images/install_from_file.png)\
and select the downloaded xpi.


## Known issues
3 changes: 3 additions & 0 deletions _locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
"advanced.autoResize.inline": {
"message": "Auto resize inline images"
},
"advanced.resizeInReplyForward.label": {
"message": "Also resize images when replying / forwarding them"
},
"advanced.orient.label": {
"message": "Automatically rotate images"
},
Expand Down
3 changes: 3 additions & 0 deletions _locales/pl/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
"advanced.autoResize.inline": {
"message": "Automatycznie zmniejszaj tylko dodane w treści"
},
"advanced.resizeInReplyForward.label": {
"message": "Zmniejszaj również obrazki w trakcie ich forwardowania / w odopowiedzi"
},
"advanced.orient.label": {
"message": "Automatycznie obróć obrazki"
},
Expand Down
7 changes: 5 additions & 2 deletions api/shrunked.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ var shrunked = class extends ExtensionCommon.ExtensionAPI {
"options.logenabled": false,
"options.contextInfo": true,
"options.autoResize": "off",
"options.resizeInReplyForward": false,
resizeAttachmentsOnSend: false,
};

Expand All @@ -292,14 +293,16 @@ var shrunked = class extends ExtensionCommon.ExtensionAPI {
return prefsToStore;
},
showNotification(tab, imageCount) {

return new Promise((resolve, reject) => {
let question = localeData.localizeMessage(
imageCount == 1 ? "question.single" : "question.plural"
);

let nativeTab = tabManager.get(tab.id).nativeTab;
//message display notification from https://github.com/jobisoft/notificationbar-API/blob/master/notificationbar/implementation.js
let notifyBox =
nativeTab.gComposeNotification || nativeTab.gNotification.notificationbox;
nativeTab.gComposeNotification || ((nativeTab.gNotification)?nativeTab.gNotification.notificationbox:null) || nativeTab.chromeBrowser.contentWindow.messageBrowser.contentWindow.gMessageNotificationBar.msgNotificationBar;
let notification = notifyBox.getNotificationWithValue("shrunked-notification");
if (imageCount == 0) {
if (notification) {
Expand Down
4 changes: 4 additions & 0 deletions api/shrunked.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@
"type":"boolean",
"optional":true
},
"resizeInReplyForward":{
"type":"boolean",
"optional":true
},
"autoResize":{
"type":"string",
"optional":true
Expand Down
45 changes: 30 additions & 15 deletions background.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,19 @@ async function shouldResize(attachment, checkSize = true) {
if (!checkSize) {
return true;
}
let { fileSizeMinimum } = await browser.storage.local.get({ fileSizeMinimum: 100 });
let file = await browser.compose.getAttachmentFile(attachment.id);
return file.size >= fileSizeMinimum * 1024;
let file = await browser.compose.getAttachmentFile(attachment.id);
return file.size >= fileSizeMinimum * 1024;
}
//get options and defaults from config
let options={}
let defaults={}
let fileSizeMinimum=100;
//check options on start and forward the logenabled/contextinfo setting to shrunked api
loadOptions().then((response)=>
{
options=response.options;
defaults=response.defaults;
fileSizeMinimum=response.fileSizeMinimum;
logenabled=response.options.logenabled;
contextInfo=response.options.contextInfo;
if(logenabled)
Expand All @@ -38,7 +39,6 @@ browser.composeScripts.register({
},
],
});

browser.runtime.onMessage.addListener(async (message, sender, callback) => {
// Image added to body of message. Return a promise to the sender.
if (message.type == "resizeFile") {
Expand All @@ -53,6 +53,11 @@ browser.runtime.onMessage.addListener(async (message, sender, callback) => {
if (message.type == "doResize") {
doResize(message.tabId, message.maxWidth, message.maxHeight, message.quality);
}
if (message.type == "getOptions") {
if(options.resizeInReplyForward)
await processAllAttachments(sender.tab,null,true);
return options;
}
return undefined;
});

Expand Down Expand Up @@ -122,12 +127,18 @@ browser.shrunked.onAttachmentContextClicked.addListener(async (tab, indicies) =>

// Message sending.
browser.compose.onBeforeSend.addListener(async (tab, details) => {
await processAllAttachments(tab,details,false);
});
async function processAllAttachments(tab, details,isOnDemand=false) {
let result = {};
let { resizeAttachmentsOnSend } = await browser.storage.local.get({
resizeAttachmentsOnSend: false,
});
if (!resizeAttachmentsOnSend) {
return result;
if(!isOnDemand)
{
let { resizeAttachmentsOnSend } = await browser.storage.local.get({
resizeAttachmentsOnSend: false,
});
if (!resizeAttachmentsOnSend) {
return result;
}
}

tabMap.delete(tab.id);
Expand All @@ -136,7 +147,7 @@ browser.compose.onBeforeSend.addListener(async (tab, details) => {
for (let a of attachments) {
if (await shouldResize(a)) {
let file = await browser.compose.getAttachmentFile(a.id);
let promise = beginResize(tab, file, false).then(async destFile => {
let promise = beginResize(tab, file, isOnDemand,false,true).then(async destFile => {
if (destFile === null) {
return;
}
Expand All @@ -152,14 +163,13 @@ browser.compose.onBeforeSend.addListener(async (tab, details) => {
if (!promises.length) {
return result;
}

await showOptionsDialog(tab);
if(!isOnDemand)
await showOptionsDialog(tab);
await Promise.all(promises).catch(() => {
result.cancel = true;
});
return result;
});

}
// Get a promise that resolves when resizing is complete.
// For auto resize we need to know if the image isInline and if this is an event that should trigger auto resize. This method is called multiple times, not only when adding attachemnt
function beginResize(tab, file, notification = true,isInline=false,shouldResizeAuto=false) {
Expand All @@ -169,6 +179,7 @@ function beginResize(tab, file, notification = true,isInline=false,shouldResizeA
}
let sourceFiles = tabMap.get(tab.id);
sourceFiles.push({ promise: { resolve, reject }, file });

//check if autoResize is on and if current event should trigger it (shouldResizeAuto) and also if auto resize is turned on for this type of image (inline/attachment)
if(options.autoResize!="off" && shouldResizeAuto && ((options.autoResize=="inline" && isInline) || (options.autoResize=="attached" && !isInline) || options.autoResize=="all"))
{
Expand Down Expand Up @@ -260,11 +271,14 @@ async function loadOptions(selectedOption=null)
"options.logenabled":false,
"options.contextInfo":true,
"options.autoResize":"off",
"options.resizeInReplyForward":false,
"default.maxWidth": 500,
"default.maxHeight": 500,
"default.quality": 75,
"default.saveDefault": true,
"fileSizeMinimum": 100
});
fileSizeMinimum=options['fileSizeMinimum'];
defaults = {
maxWidth: options['default.maxWidth'],
maxHeight: options['default.maxHeight'],
Expand All @@ -280,11 +294,12 @@ async function loadOptions(selectedOption=null)
logenabled: options["options.logenabled"],
contextInfo: options["options.contextInfo"],
autoResize:options["options.autoResize"],
resizeInReplyForward:options["options.resizeInReplyForward"]
};

}

return {"options":options,"defaults":defaults};
return {"options":options,"defaults":defaults,"fileSizeMinimum":fileSizeMinimum};
}
function cancelResize(tabId) {
if (!tabMap.has(tabId)) {
Expand Down
48 changes: 37 additions & 11 deletions compose_script.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,47 @@ let config = {
characterData: false,
subtree: true,
};
let logenabled=false;
let resizeWhenForwardReply= false;
let logenabled = false;
async function startup(){
browser.runtime.sendMessage({
type: "getOptions",
}).then((response)=>{
resizeWhenForwardReply=response["resizeInReplyForward"];
logenabled = response["logenabled"];
if(resizeWhenForwardReply)
parseInlineAtStart();
})



}
startup();
let observer = new MutationObserver(function(mutations) {
for (let mutation of mutations) {
if (mutation.addedNodes && mutation.addedNodes.length) {
if(logenabled)
console.log("Nodes added to message: " + mutation.addedNodes.length);
console.log("Nodes added to message: " + mutation.addedNodes.length);
for (let target of mutation.addedNodes) {
maybeResizeInline(target);
}
}
}
});
observer.observe(document.body, config);
browser.storage.local.get({
"options.logenabled": false,
}).then((response) =>

async function parseInlineAtStart()
{
logenabled = logenabled["options.logenabled"];
});
if(logenabled)
console.log(`parsing inline images at compose start`);
let existingInline=document.body.getElementsByTagName("IMG");
for(let i=0;i<existingInline.length;i++)
{
if(logenabled)
console.log(`parsing image ${i}, node ${existingInline[i].nodeName}`);
await maybeResizeInline(existingInline[i]);
}
}

async function maybeResizeInline(target) {
if (target.nodeName == "IMG") {
Expand All @@ -40,12 +62,12 @@ async function maybeResizeInline(target) {
console.log("Not resizing - image is part of signature");
return;
}
if (parent.getAttribute("type") == "cite") {
if (parent.getAttribute("type") == "cite" && resizeWhenForwardReply==false) {
if (logenabled)
console.log("Not resizing - image is part of message being replied to");
return;
}
if (parent.classList.contains("moz-forward-container")) {
if (parent.classList.contains("moz-forward-container") && resizeWhenForwardReply==false) {
if (logenabled)
console.log("Not resizing - image is part of forwarded message");
return;
Expand Down Expand Up @@ -116,8 +138,12 @@ async function maybeResizeInline(target) {
let destFile = await browser.runtime.sendMessage({
type: "resizeFile",
file: srcFile,
}).catch((err) => {
console.error(err);
return;
});
if (destFile === null) {

if (destFile === null || destFile === undefined) {
return;
}
let destURL = await new Promise(resolve => {
Expand All @@ -131,7 +157,7 @@ async function maybeResizeInline(target) {
};
reader.readAsDataURL(destFile);
});

target.setAttribute("src", destURL);
target.removeAttribute("width");
target.removeAttribute("height");
Expand Down
5 changes: 4 additions & 1 deletion content/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ async function getAll() {
"options.logenabled":false,
"options.contextInfo":false,
"options.autoResize":"off",
"options.resizeInReplyForward": false,
resizeAttachmentsOnSend: false,
});

Expand Down Expand Up @@ -71,6 +72,7 @@ async function getAll() {
cb_logenabled.checked=prefs["options.logenabled"]
cb_contextInfoEnabled.checked=prefs["options.contextInfo"]
s_autoResize.value=prefs["options.autoResize"]
cb_forwardReplyResize.checked=prefs["options.resizeInReplyForward"]
// cb_logenabled.checked = prefs["log.enabled"];
s_resizeonsend.value = prefs.resizeAttachmentsOnSend;

Expand Down Expand Up @@ -112,6 +114,7 @@ addEventListener("load", async () => {
cb_logenabled.addEventListener("change", setCheckbox);
cb_contextInfoEnabled.addEventListener("change", setCheckbox);
s_autoResize.addEventListener("change", setAutoResizeOption);
cb_forwardReplyResize.addEventListener("change", setCheckbox);
browser.storage.onChanged.addListener(() => {
if (!settingFromThisPage) {
getAll();
Expand Down Expand Up @@ -191,4 +194,4 @@ async function setAutoResizeOption() {
"options.autoResize": s_autoResize.value,
});
settingFromThisPage = false;
}
}
1 change: 1 addition & 0 deletions content/config.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
</div>
<label><input type="checkbox" id="cb_logenabled" name="options.logenabled" /><span data-l10n-content="advanced.logenabled.label"></span></label>
<label><input type="checkbox" id="cb_contextInfoEnabled" name="options.contextInfo" /><span data-l10n-content="advanced.contextInfo.label"></span></label>
<label><input type="checkbox" id="cb_forwardReplyResize" name="options.resizeInReplyForward" /><span data-l10n-content="advanced.resizeInReplyForward.label"></span></label>
<div id="b_autoResize">
<label data-l10n-content="advanced.autoResize.label" />
<select id="s_autoResize">
Expand Down
Binary file added images/notification.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/options.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/popup.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "__MSG_extensionName__",
"description": "__MSG_extensionDescription__",
"version": "5.7.2",
"version": "5.8.0",
"applications": {
"gecko": {
"id": "[email protected]",
Expand Down

0 comments on commit 20e35b9

Please sign in to comment.