From 7a6927ceeca763292e41d349ef33a2bcdb00f4ae Mon Sep 17 00:00:00 2001 From: mic Date: Fri, 26 Dec 2025 11:37:25 +0100 Subject: [PATCH 1/8] dynamic placeholder methods added. see #527 --- _locales/en/messages.json | 4 +++ js/mzta-placeholders.js | 63 +++++++++++++++++++++++++++++++++++---- 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 904229c1..a2d5a902 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -619,6 +619,10 @@ "message": "Folder path", "description": "" }, + "placeholder_mail_headers": { + "message": "Mail headers", + "description": "" + }, "placeholder_selected_text": { "message": "Selected text", "description": "" diff --git a/js/mzta-placeholders.js b/js/mzta-placeholders.js index 0eb6f926..c211ac11 100644 --- a/js/mzta-placeholders.js +++ b/js/mzta-placeholders.js @@ -17,6 +17,7 @@ */ import { prefs_default } from '../options/mzta-options-default.js'; +import { getMailHeader } from './mzta-utils.js'; /* ================= PLACEHOLDERS PROPERTIES ======================================== @@ -35,6 +36,10 @@ import { prefs_default } from '../options/mzta-options-default.js'; 0: Custom placeholder 1: Default placeholder (not editable, cannot be deleted) + is_dynamic attribute: + 0: it's a fixed placeholder + 1: it's a dynamic placehoder (it means that it will have a : and then a value, like {%my_placeholder:test_value%}) + ================ USER PROPERTIES enabled attribute: 0: Disabled @@ -53,6 +58,7 @@ const defaultPlaceholders = [ default_value: "", type: 0, is_default: "1", + is_dynamic: "0", enabled: 1, }, { @@ -61,6 +67,7 @@ const defaultPlaceholders = [ default_value: "", type: 0, is_default: "1", + is_dynamic: "0", enabled: 1, }, { @@ -69,6 +76,7 @@ const defaultPlaceholders = [ default_value: "", type: 2, is_default: "1", + is_dynamic: "0", enabled: 1, }, { @@ -77,6 +85,7 @@ const defaultPlaceholders = [ default_value: "", type: 2, is_default: "1", + is_dynamic: "0", enabled: 1, }, { @@ -85,6 +94,7 @@ const defaultPlaceholders = [ default_value: "", type: 0, is_default: "1", + is_dynamic: "0", enabled: 1, }, { @@ -93,6 +103,7 @@ const defaultPlaceholders = [ default_value: "", type: 1, is_default: "1", + is_dynamic: "0", enabled: 1, }, { @@ -101,6 +112,16 @@ const defaultPlaceholders = [ default_value: "", type: 1, is_default: "1", + is_dynamic: "0", + enabled: 1, + }, + { + id: 'mail_headers', + name: "__MSG_placeholder_mail_headers__", + default_value: "", + type: 1, + is_default: "1", + is_dynamic: "1", enabled: 1, }, { @@ -109,6 +130,7 @@ const defaultPlaceholders = [ default_value: "", type: 0, is_default: "1", + is_dynamic: "0", enabled: 1, }, { @@ -117,6 +139,7 @@ const defaultPlaceholders = [ default_value: "", type: 0, is_default: "1", + is_dynamic: "0", enabled: 1, }, { @@ -125,6 +148,7 @@ const defaultPlaceholders = [ default_value: "", type: 0, is_default: "1", + is_dynamic: "0", enabled: 1, }, { @@ -133,6 +157,7 @@ const defaultPlaceholders = [ default_value: "0", type: 1, is_default: "1", + is_dynamic: "0", enabled: 1, }, { @@ -141,6 +166,7 @@ const defaultPlaceholders = [ default_value: "", type: 0, is_default: "1", + is_dynamic: "0", enabled: 1, }, { @@ -149,6 +175,7 @@ const defaultPlaceholders = [ default_value: "", type: 0, is_default: "1", + is_dynamic: "0", enabled: 1, }, { @@ -157,6 +184,7 @@ const defaultPlaceholders = [ default_value: "", type: 0, is_default: "1", + is_dynamic: "0", enabled: 1, }, { @@ -165,6 +193,7 @@ const defaultPlaceholders = [ default_value: "", type: 1, is_default: "1", + is_dynamic: "0", enabled: 1, }, { @@ -173,6 +202,7 @@ const defaultPlaceholders = [ default_value: "", type: 0, is_default: "1", + is_dynamic: "0", enabled: 1, }, { @@ -181,6 +211,7 @@ const defaultPlaceholders = [ default_value: "", type: 0, is_default: "1", + is_dynamic: "0", enabled: 1, }, { @@ -189,6 +220,7 @@ const defaultPlaceholders = [ default_value: "", type: 0, is_default: "1", + is_dynamic: "0", enabled: 1, }, { @@ -197,6 +229,7 @@ const defaultPlaceholders = [ default_value: "", type: 0, is_default: "1", + is_dynamic: "0", enabled: 1, }, { @@ -205,6 +238,7 @@ const defaultPlaceholders = [ default_value: "", type: 0, is_default: "1", + is_dynamic: "0", enabled: 1, }, { @@ -213,6 +247,7 @@ const defaultPlaceholders = [ default_value: "", type: 0, is_default: "1", + is_dynamic: "0", enabled: 1, }, { @@ -221,6 +256,7 @@ const defaultPlaceholders = [ default_value: "", type: 0, is_default: "1", + is_dynamic: "0", enabled: 1, }, { @@ -229,6 +265,7 @@ const defaultPlaceholders = [ default_value: "", type: 1, is_default: "1", + is_dynamic: "0", enabled: 1, } ]; @@ -269,6 +306,7 @@ export async function setCustomPlaceholders(placeholders) { placeholders.forEach(ph => { ph.id = placeholdersUtils.validateCustomDataPH_ID(ph.id); ph.is_default = "0"; + ph.is_dynamic = "0"; }); await browser.storage.local.set({_custom_placeholder: placeholders}); } @@ -330,10 +368,21 @@ export const placeholdersUtils = { // Use exec to find all matches while ((match = regex.exec(text)) !== null) { - const foundPH = activePHs.find(ph => ph.id === match[1].trim()); - if (foundPH) { - matches.push(foundPH); - } + console.log(">>>>>>>>>> extractPlaceholders match: " + JSON.stringify(match)); + const foundPH = activePHs.find(ph => ph.id === match[1].trim() || (ph.is_dynamic == 1 && match[1].startsWith(ph.id + ':'))); + if (foundPH) { + if (foundPH.is_dynamic == 1 && match[1].includes(':')) { + const [id, custom_value] = match[1].split(':', 2); + const dynamicPH = { ...foundPH }; // Create a copy to avoid modifying the original + dynamicPH.id = id.trim(); + dynamicPH.custom_value = custom_value.trim(); + matches.push(dynamicPH); + console.log(">>>>>>>>>> extractPlaceholders dynamicPH: " + JSON.stringify(dynamicPH)); + } else { + matches.push(foundPH); + console.log(">>>>>>>>>> extractPlaceholders foundPH: " + JSON.stringify(foundPH)); + } + } } return matches; @@ -424,6 +473,7 @@ export const placeholdersUtils = { // console.log(">>>>>>>>>> curr_message: " + JSON.stringify(curr_message)); let finalSubs = {}; for(let currPH of currPHs){ + console.log(">>>>>>>>>> currPH: " + JSON.stringify(currPH)); switch(currPH.id){ case 'mail_text_body': finalSubs['mail_text_body'] = placeholdersUtils.failSafePlaceholders(body_text); @@ -446,8 +496,11 @@ export const placeholdersUtils = { case 'mail_folder_path': finalSubs['mail_folder_path'] = placeholdersUtils.failSafePlaceholders(curr_message.folder?.path); break; + case 'mail_headers': + finalSubs['mail_headers'] = placeholdersUtils.failSafePlaceholders(getMailHeader(curr_message, currPH.original_value)); + break; case 'selected_text': - finalSubs['selected_text'] = placeholdersUtils.failSafePlaceholders(selection_text); + finalSubs['selected_text:'+currPH.original_value] = placeholdersUtils.failSafePlaceholders(selection_text); break; case 'selected_html': finalSubs['selected_html'] = placeholdersUtils.failSafePlaceholders(selection_html); From 61c7edc54413dd5edcef60981c902a6dc96be057 Mon Sep 17 00:00:00 2001 From: mic Date: Fri, 26 Dec 2025 11:45:05 +0100 Subject: [PATCH 2/8] var name fixed. see #527 --- js/mzta-placeholders.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/mzta-placeholders.js b/js/mzta-placeholders.js index c211ac11..f4ec7bb5 100644 --- a/js/mzta-placeholders.js +++ b/js/mzta-placeholders.js @@ -497,7 +497,7 @@ export const placeholdersUtils = { finalSubs['mail_folder_path'] = placeholdersUtils.failSafePlaceholders(curr_message.folder?.path); break; case 'mail_headers': - finalSubs['mail_headers'] = placeholdersUtils.failSafePlaceholders(getMailHeader(curr_message, currPH.original_value)); + finalSubs['mail_headers'] = placeholdersUtils.failSafePlaceholders(getMailHeader(curr_message, currPH.custom_value)); break; case 'selected_text': finalSubs['selected_text:'+currPH.original_value] = placeholdersUtils.failSafePlaceholders(selection_text); From 633f0dc3e29aa5fc2bc170fdff3fb0726a988f6e Mon Sep 17 00:00:00 2001 From: mic Date: Fri, 26 Dec 2025 11:45:20 +0100 Subject: [PATCH 3/8] getMailHeader method added. see #527 --- js/mzta-utils.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/js/mzta-utils.js b/js/mzta-utils.js index 24cb954c..e087308e 100644 --- a/js/mzta-utils.js +++ b/js/mzta-utils.js @@ -189,6 +189,17 @@ export async function replaceBody(tabId, replyHtml) { await messenger.compose.setComposeDetails(tabId, {body: fullBody}); } +export async function getMailHeader(curr_message, mail_header_id) { + let mail_header_value = ""; + let full_message = await browser.messages.getFull(curr_message.id); + console.log(">>>>>>>>>>>> getMailHeader full_message: " + JSON.stringify(full_message)); + if(full_message.hasOwnProperty("headers") && Object.keys(full_message.headers).some(header => header.toLowerCase() === mail_header_id.toLowerCase())){ + mail_header_value = full_message.headers[Object.keys(full_message.headers).find(header => header.toLowerCase() === mail_header_id.toLowerCase())]; + } + console.log(">>>>>>>>>>>> getMailHeader mail_header_value: " + mail_header_value) + return mail_header_value; +} + export function sanitizeHtml(input) { // Keep only
tags and remove all other HTML tags return input.replace(/<(?!br\s*\/?)[^>]+>/gi, ''); From 06c13a4f810cc981a976ce42b265f8c2484becdd Mon Sep 17 00:00:00 2001 From: mic Date: Fri, 26 Dec 2025 11:47:05 +0100 Subject: [PATCH 4/8] using the correct dynamic id for the substitution. see #527 --- js/mzta-placeholders.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/mzta-placeholders.js b/js/mzta-placeholders.js index f4ec7bb5..e2506f90 100644 --- a/js/mzta-placeholders.js +++ b/js/mzta-placeholders.js @@ -497,7 +497,7 @@ export const placeholdersUtils = { finalSubs['mail_folder_path'] = placeholdersUtils.failSafePlaceholders(curr_message.folder?.path); break; case 'mail_headers': - finalSubs['mail_headers'] = placeholdersUtils.failSafePlaceholders(getMailHeader(curr_message, currPH.custom_value)); + finalSubs['mail_headers:' + currPH.custom_value] = placeholdersUtils.failSafePlaceholders(getMailHeader(curr_message, currPH.custom_value)); break; case 'selected_text': finalSubs['selected_text:'+currPH.original_value] = placeholdersUtils.failSafePlaceholders(selection_text); From 5521945d70de46e8068c702637772a9b7453c9ba Mon Sep 17 00:00:00 2001 From: mic Date: Fri, 26 Dec 2025 11:47:24 +0100 Subject: [PATCH 5/8] fixed wrong line modified --- js/mzta-placeholders.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/mzta-placeholders.js b/js/mzta-placeholders.js index e2506f90..b57ac76a 100644 --- a/js/mzta-placeholders.js +++ b/js/mzta-placeholders.js @@ -500,7 +500,7 @@ export const placeholdersUtils = { finalSubs['mail_headers:' + currPH.custom_value] = placeholdersUtils.failSafePlaceholders(getMailHeader(curr_message, currPH.custom_value)); break; case 'selected_text': - finalSubs['selected_text:'+currPH.original_value] = placeholdersUtils.failSafePlaceholders(selection_text); + finalSubs['selected_text'] = placeholdersUtils.failSafePlaceholders(selection_text); break; case 'selected_html': finalSubs['selected_html'] = placeholdersUtils.failSafePlaceholders(selection_html); From f22482d083bc1c2fe594b0f17af020a693f971bb Mon Sep 17 00:00:00 2001 From: mic Date: Fri, 26 Dec 2025 11:49:36 +0100 Subject: [PATCH 6/8] console.log debug line added --- js/mzta-placeholders.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/mzta-placeholders.js b/js/mzta-placeholders.js index b57ac76a..00f8bdf7 100644 --- a/js/mzta-placeholders.js +++ b/js/mzta-placeholders.js @@ -559,7 +559,7 @@ export const placeholdersUtils = { break; } } - + console.log(">>>>>>>>>> finalSubs: " + JSON.stringify(finalSubs)); return finalSubs; }, From 049b88302a04a79e9b7a4ac258c32fe40a1dcbcc Mon Sep 17 00:00:00 2001 From: mic Date: Fri, 26 Dec 2025 11:51:34 +0100 Subject: [PATCH 7/8] if it's async, you have to wait..... --- js/mzta-placeholders.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/mzta-placeholders.js b/js/mzta-placeholders.js index 00f8bdf7..e8a222ae 100644 --- a/js/mzta-placeholders.js +++ b/js/mzta-placeholders.js @@ -497,7 +497,7 @@ export const placeholdersUtils = { finalSubs['mail_folder_path'] = placeholdersUtils.failSafePlaceholders(curr_message.folder?.path); break; case 'mail_headers': - finalSubs['mail_headers:' + currPH.custom_value] = placeholdersUtils.failSafePlaceholders(getMailHeader(curr_message, currPH.custom_value)); + finalSubs['mail_headers:' + currPH.custom_value] = placeholdersUtils.failSafePlaceholders(await getMailHeader(curr_message, currPH.custom_value)); break; case 'selected_text': finalSubs['selected_text'] = placeholdersUtils.failSafePlaceholders(selection_text); From 5e8015161b030008da2225aa93f28ffd8f1ef31a Mon Sep 17 00:00:00 2001 From: mic Date: Fri, 26 Dec 2025 12:09:26 +0100 Subject: [PATCH 8/8] correctly substituting text for a dynamic placeholder see #527 --- js/mzta-placeholders.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/js/mzta-placeholders.js b/js/mzta-placeholders.js index e8a222ae..7308a4a2 100644 --- a/js/mzta-placeholders.js +++ b/js/mzta-placeholders.js @@ -395,13 +395,17 @@ export const placeholdersUtils = { use_default_value = false, skip_additional_text = false } = args || {}; + console.log(">>>>>>>>>> replacePlaceholders replacements: " + JSON.stringify(replacements)); // Regular expression to match patterns like {%...%} return text.replace(/{%\s*(.*?)\s*%}/g, function(match, p1) { + console.log(">>>>>>>>>> replacePlaceholders match: " + JSON.stringify(match)); + console.log(">>>>>>>>>> replacePlaceholders p1: " + JSON.stringify(p1)); // p1 contains the key inside {% %} if (skip_additional_text && (p1 === 'additional_text')) { return match; } - const currPlaceholder = defaultPlaceholders.find(ph => ph.id === p1); + const currPlaceholder = defaultPlaceholders.find(ph => (ph.id === p1) || (ph.is_dynamic == 1 && p1.startsWith(ph.id + ':'))); + console.log(">>>>>>>>>> replacePlaceholders currPlaceholder: " + JSON.stringify(currPlaceholder)); if (!currPlaceholder) { return match; }