From 2740fe3ee9a961e29727c71dfc68fe7b6037ad67 Mon Sep 17 00:00:00 2001 From: mic Date: Tue, 10 Feb 2026 21:36:59 +0100 Subject: [PATCH 01/16] additional_text is now dynamic. see #525 #554 --- js/mzta-placeholders.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/mzta-placeholders.js b/js/mzta-placeholders.js index d8b63008..171267fb 100644 --- a/js/mzta-placeholders.js +++ b/js/mzta-placeholders.js @@ -148,7 +148,7 @@ const defaultPlaceholders = [ default_value: "", type: 0, is_default: "1", - is_dynamic: "0", + is_dynamic: "1", enabled: 1, }, { @@ -427,7 +427,7 @@ export const placeholdersUtils = { // 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')) { + if (skip_additional_text && ((p1 === 'additional_text') || (p1.startsWith('additional_text:')))) { return match; } const currPlaceholder = defaultPlaceholders.find(ph => (ph.id === p1) || (ph.is_dynamic == 1 && p1.startsWith(ph.id + ':'))); From 34e8e242f6f066f813493a2f6765909d41eab5e2 Mon Sep 17 00:00:00 2001 From: mic Date: Tue, 10 Feb 2026 21:42:26 +0100 Subject: [PATCH 02/16] hasPlaceholder and replacePlaceholder can now work with dynamic placeholders. see #525 #554 --- js/mzta-placeholders.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/mzta-placeholders.js b/js/mzta-placeholders.js index 171267fb..2b05e7d1 100644 --- a/js/mzta-placeholders.js +++ b/js/mzta-placeholders.js @@ -436,7 +436,7 @@ export const placeholdersUtils = { return match; } // Replace if found, otherwise keep the original or substitute with default value - return replacements[p1] || (use_default_value ? currPlaceholder.default_value : match); + return replacements[p1] || replacements[currPlaceholder.id] || (use_default_value ? currPlaceholder.default_value : match); }); }, @@ -459,7 +459,7 @@ export const placeholdersUtils = { // If a specific placeholder is provided, we search for it if (placeholder !== "") { // Dynamically build the regex for the specific placeholder - regex = new RegExp(`{%\s*${placeholder}\s*%}`); + regex = new RegExp(`{%\s*${placeholder}(:.*?)?\s*%}`); } else { // Otherwise, we search for any placeholder in the format {% ... %} regex = /{%\s*(.*?)\s*%}/; From b1282c956216715d182addd6b146072a9c1e30e8 Mon Sep 17 00:00:00 2001 From: mic Date: Wed, 11 Feb 2026 21:30:56 +0100 Subject: [PATCH 03/16] getPlaceholdersAdditionalTextArray method added. see #525 #554 --- js/mzta-placeholders.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/js/mzta-placeholders.js b/js/mzta-placeholders.js index 2b05e7d1..b06f82d3 100644 --- a/js/mzta-placeholders.js +++ b/js/mzta-placeholders.js @@ -485,6 +485,19 @@ export const placeholdersUtils = { return regex.test(text); }, + getPlaceholdersAdditionalTextArray(prompt_text){ + const regex = /{%\s*additional_text(?::(.*?))?\s*%}/g; + let matches = []; + let match; + while ((match = regex.exec(prompt_text)) !== null) { + matches.push({ + placeholder: match[0], + info: match[1] ? match[1].trim() : "" + }); + } + return matches; + }, + async getPlaceholdersValues(args) { const { prompt_text = "", From c29b4b335295da9929b88a835a43534fa074bb77 Mon Sep 17 00:00:00 2001 From: mic Date: Wed, 11 Feb 2026 21:45:48 +0100 Subject: [PATCH 04/16] userInput is now an array. see #525 #554 --- api_webchat/controller.js | 11 +++++++++-- js/mzta-menus.js | 7 +++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/api_webchat/controller.js b/api_webchat/controller.js index 8b722a25..2525069e 100644 --- a/api_webchat/controller.js +++ b/api_webchat/controller.js @@ -262,7 +262,7 @@ browser.runtime.onMessage.addListener((message, sender, sendResponse) => { } break; case 'api_send_custom_text': - let userInput = message.custom_text; + let userInput = message.custom_text; // From version 4.0.0 this is an array if(userInput !== null) { if(!placeholdersUtils.hasPlaceholder(promptData.prompt, 'additional_text')){ // no additional_text placeholder, do as usual @@ -270,7 +270,14 @@ browser.runtime.onMessage.addListener((message, sender, sendResponse) => { }else{ // we have the additional_text placeholder, do the magic! let finalSubs = {}; - finalSubs["additional_text"] = userInput; + + if (Array.isArray(userInput)) { + userInput.forEach(obj => { + finalSubs[obj.placeholder.replace(/^{%|%}$/g, '').trim()] = obj.custom_text; + }); + } else { + finalSubs["additional_text"] = userInput; + } promptData.prompt = placeholdersUtils.replacePlaceholders({ text: promptData.prompt, replacements: finalSubs, diff --git a/js/mzta-menus.js b/js/mzta-menus.js index 4d04dcaf..b29ad6cc 100644 --- a/js/mzta-menus.js +++ b/js/mzta-menus.js @@ -192,6 +192,13 @@ export class mzta_Menus { only_quoted_text: only_quoted_text, tags_full_list: tags_full_list }); + + curr_prompt.custom_text_array = {}; + + if(placeholdersUtils.hasPlaceholder(curr_prompt.text, 'additional_text')){ + curr_prompt.custom_text_array = placeholdersUtils.getPlaceholdersAdditionalTextArray(curr_prompt.text); + } + console.log(">>>>>>>>>>>>>>>>>>> curr_prompt.custom_text_array: " + JSON.stringify(curr_prompt.custom_text_array)); switch(curr_prompt.id){ case 'prompt_translate_this': From 3213a71eba24b13e3335936136d51a567bea022c Mon Sep 17 00:00:00 2001 From: mic Date: Wed, 11 Feb 2026 21:55:04 +0100 Subject: [PATCH 05/16] the additional text is now an array. see #525 #554 --- api_webchat/controller.js | 2 +- api_webchat/messageInput.js | 54 ++++++++++++++++++++++++++++++------- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/api_webchat/controller.js b/api_webchat/controller.js index 2525069e..c6f349c9 100644 --- a/api_webchat/controller.js +++ b/api_webchat/controller.js @@ -256,7 +256,7 @@ browser.runtime.onMessage.addListener((message, sender, sendResponse) => { promptData = message; //send the received prompt to the llm api if(message.do_custom_text=="1") { - messageInput._showCustomTextField(); + messageInput._showCustomTextField(message.prompt_info?.custom_text_array); }else{ sendPrompt(message); } diff --git a/api_webchat/messageInput.js b/api_webchat/messageInput.js index b5b2a6b0..9007691d 100644 --- a/api_webchat/messageInput.js +++ b/api_webchat/messageInput.js @@ -193,6 +193,8 @@ messageInputTemplate.content.appendChild(customDiv); class MessageInput extends HTMLElement { model = ''; + _customTextArray = []; + _currentCustomTextIndex = 0; constructor() { super(); @@ -306,21 +308,55 @@ class MessageInput extends HTMLElement { this._messageInputField.value = msg; } - _showCustomTextField(){ + _showCustomTextField(custom_text_array){ + this._customTextArray = custom_text_array || []; + if (this._customTextArray.length === 0) { + this._customTextArray.push({ placeholder: "{%additional_text%}", info: "" }); + } + this._currentCustomTextIndex = 0; + this._renderCustomTextStep(); this._customText.style.display = 'block'; + } + + _renderCustomTextStep() { + const currentItem = this._customTextArray[this._currentCustomTextIndex]; + const infoDiv = this.shadowRoot.querySelector('#mzta-custom_info'); + + this._customTextArea.value = ""; + + if (currentItem.info && currentItem.info.trim() !== "") { + infoDiv.textContent = currentItem.info; + } else { + infoDiv.textContent = browser.i18n.getMessage("chatgpt_win_custom_text"); + } + this._customTextArea.focus(); } async _customTextBtnClick(args) { const customText = this._customTextArea.value; - // console.log(">>>>>>>>>>>>>>>> customText: " + customText); - args.customBtn.disabled = true; - args.customBtn.classList.add('disabled'); - args.customLoading.style.display = 'inline-block'; - args.customLoading.style.display = 'none'; - let tab = await browser.tabs.query({ active: true, currentWindow: true }); - browser.runtime.sendMessage({ command: "api_send_custom_text", custom_text: customText, tabId: tab[0].id }); - args.customDiv.style.display = 'none'; + + if (this._customTextArray[this._currentCustomTextIndex]) { + this._customTextArray[this._currentCustomTextIndex].custom_text = customText; + } + + this._currentCustomTextIndex++; + + if (this._currentCustomTextIndex < this._customTextArray.length) { + this._renderCustomTextStep(); + } else { + args.customBtn.disabled = true; + args.customBtn.classList.add('disabled'); + args.customLoading.style.display = 'inline-block'; + + let tab = await browser.tabs.query({ active: true, currentWindow: true }); + browser.runtime.sendMessage({ command: "api_send_custom_text", custom_text: this._customTextArray, tabId: tab[0].id }); + args.customDiv.style.display = 'none'; + + args.customBtn.disabled = false; + args.customBtn.classList.remove('disabled'); + args.customLoading.style.display = 'none'; + } } } From ded59f14f757ff8c8817a61d9297d80cc9d99d18 Mon Sep 17 00:00:00 2001 From: mic Date: Wed, 11 Feb 2026 22:47:41 +0100 Subject: [PATCH 06/16] checkPromptsConfigForPlaceholders updated. see #525 #554 --- pages/customprompts/mzta-custom-prompts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/customprompts/mzta-custom-prompts.js b/pages/customprompts/mzta-custom-prompts.js index 55824f0d..8e45ac8c 100644 --- a/pages/customprompts/mzta-custom-prompts.js +++ b/pages/customprompts/mzta-custom-prompts.js @@ -1417,7 +1417,7 @@ async function checkPromptsConfigForPlaceholders(textarea){ // check additional_text and selected_text placeholders presence and the corrispondent checkboxes let tr_ancestor = textarea.closest('tr'); let need_custom_text_element = tr_ancestor.querySelector('.need_custom_text') || tr_ancestor.querySelector('.need_custom_text_new'); - if(String(curr_text).indexOf('{%additional_text%}') != -1){ + if(/{%\s*additional_text(?::.*?)?\s*%}/.test(String(curr_text))){ if(!need_custom_text_element.checked){ need_custom_text_element.closest('.need_custom_text_span').style.border = '2px solid red'; }else{ From e30d073bca8b1f012c53d103e6de06bac2c8c580 Mon Sep 17 00:00:00 2001 From: mic Date: Wed, 11 Feb 2026 23:10:33 +0100 Subject: [PATCH 07/16] handling multiple old {%additional_text%} placeholders. see #525 #554 #652 --- js/mzta-utils-prompt.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/js/mzta-utils-prompt.js b/js/mzta-utils-prompt.js index c19499f8..b8a58ac8 100644 --- a/js/mzta-utils-prompt.js +++ b/js/mzta-utils-prompt.js @@ -59,6 +59,13 @@ export const taPromptUtils = { if(placeholdersUtils.hasCustomPlaceholder(curr_prompt.text)){ curr_prompt.text = await placeholdersUtils.replaceCustomPlaceholders(curr_prompt.text); } + + // Replace all {%additional_text%} with {%additional_text:N%} + let additionalTextCounter = 1; + curr_prompt.text = curr_prompt.text.replace(/{%\s*additional_text\s*%}/g, () => { + return `{%additional_text:${additionalTextCounter++}%}`; + }); + let finalSubs = await placeholdersUtils.getPlaceholdersValues({ prompt_text: curr_prompt.text, curr_message: curr_message, From 41dbb5d009ae2b927107379ca0208c2ea8fb46ec Mon Sep 17 00:00:00 2001 From: mic Date: Thu, 12 Feb 2026 21:57:52 +0100 Subject: [PATCH 08/16] # added to additional_text without id. see #525 #554 --- js/mzta-utils-prompt.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/mzta-utils-prompt.js b/js/mzta-utils-prompt.js index b8a58ac8..28978662 100644 --- a/js/mzta-utils-prompt.js +++ b/js/mzta-utils-prompt.js @@ -63,7 +63,7 @@ export const taPromptUtils = { // Replace all {%additional_text%} with {%additional_text:N%} let additionalTextCounter = 1; curr_prompt.text = curr_prompt.text.replace(/{%\s*additional_text\s*%}/g, () => { - return `{%additional_text:${additionalTextCounter++}%}`; + return `{%additional_text:#${additionalTextCounter++}%}`; }); let finalSubs = await placeholdersUtils.getPlaceholdersValues({ From 774ffc2287f9e84243f9970803788f712547caa3 Mon Sep 17 00:00:00 2001 From: mic Date: Thu, 12 Feb 2026 22:10:12 +0100 Subject: [PATCH 09/16] additional_text now printed on the form. see #525 #554 --- api_webchat/messageInput.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/api_webchat/messageInput.js b/api_webchat/messageInput.js index 9007691d..bb0bbdf3 100644 --- a/api_webchat/messageInput.js +++ b/api_webchat/messageInput.js @@ -100,6 +100,9 @@ messagesInputStyle.textContent = ` padding-bottom:10px; font-size:15px; } + #mzta-custom_info span{ + font-size:0.8em; + } @media (prefers-color-scheme: dark) { #messageInputField { background-color: #303030; @@ -323,11 +326,13 @@ class MessageInput extends HTMLElement { const infoDiv = this.shadowRoot.querySelector('#mzta-custom_info'); this._customTextArea.value = ""; + infoDiv.textContent = browser.i18n.getMessage("chatgpt_win_custom_text"); if (currentItem.info && currentItem.info.trim() !== "") { - infoDiv.textContent = currentItem.info; - } else { - infoDiv.textContent = browser.i18n.getMessage("chatgpt_win_custom_text"); + infoDiv.appendChild(document.createElement("br")); + const infoSpan = document.createElement("span"); + infoSpan.textContent = "[" + browser.i18n.getMessage("customPrompts_form_label_ID") + ": " + currentItem.info + "]"; + infoDiv.appendChild(infoSpan); } this._customTextArea.focus(); From 28afa0fc456cba137f8de0be9486c8c5d43d9b5c Mon Sep 17 00:00:00 2001 From: mic Date: Thu, 12 Feb 2026 22:29:24 +0100 Subject: [PATCH 10/16] bigger form. see #525 #554 --- api_webchat/messageInput.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/api_webchat/messageInput.js b/api_webchat/messageInput.js index bb0bbdf3..c7e704d8 100644 --- a/api_webchat/messageInput.js +++ b/api_webchat/messageInput.js @@ -69,12 +69,14 @@ messagesInputStyle.textContent = ` } #mzta-custom_text{ padding:10px; - width:auto; + width:50%; + min-width:300px; max-width:80%; height:auto; max-height:80%; border-radius:5px; - overflow:auto; + overflow-y:auto; + overflow-x:hidden; position:fixed; top:50%; left:50%; @@ -84,15 +86,18 @@ messagesInputStyle.textContent = ` background:#333; color:white; border:3px solid white; + box-sizing: border-box; } #mzta-custom_loading{ height:50px;display:none; } #mzta-custom_textarea{ color:black; - padding:1px; + padding:5px; font-size:15px; width:100%; + box-sizing: border-box; + resize: vertical; } #mzta-custom_info{ text-align:center; @@ -181,6 +186,7 @@ customInfo.textContent = browser.i18n.getMessage("chatgpt_win_custom_text"); customDiv.appendChild(customInfo); const customTextArea = document.createElement('textarea'); customTextArea.id = 'mzta-custom_textarea'; +customTextArea.rows = 5; customDiv.appendChild(customTextArea); const customLoading = document.createElement('img'); customLoading.src = browser.runtime.getURL("/images/loading.gif"); From 28e3b6502851bcbd7fdfd6f7456824f897354f8d Mon Sep 17 00:00:00 2001 From: mic Date: Thu, 12 Feb 2026 22:38:02 +0100 Subject: [PATCH 11/16] progressive numbers added. see #525 #554 --- api_webchat/messageInput.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/api_webchat/messageInput.js b/api_webchat/messageInput.js index c7e704d8..1e226c15 100644 --- a/api_webchat/messageInput.js +++ b/api_webchat/messageInput.js @@ -108,6 +108,13 @@ messagesInputStyle.textContent = ` #mzta-custom_info span{ font-size:0.8em; } + #mzta-custom_step{ + position: absolute; + bottom: 5px; + right: 10px; + font-size: 12px; + color: #ccc; + } @media (prefers-color-scheme: dark) { #messageInputField { background-color: #303030; @@ -197,6 +204,9 @@ customBtn.id = 'mzta-custom_btn'; customBtn.textContent = browser.i18n.getMessage("chatgpt_win_send"); customBtn.classList.add('mzta-btn'); customDiv.appendChild(customBtn); +const customStep = document.createElement('div'); +customStep.id = 'mzta-custom_step'; +customDiv.appendChild(customStep); messageInputTemplate.content.appendChild(customDiv); class MessageInput extends HTMLElement { @@ -223,6 +233,7 @@ class MessageInput extends HTMLElement { this._customTextArea = shadowRoot.querySelector('#mzta-custom_textarea'); this._customLoading = shadowRoot.querySelector('#mzta-custom_loading'); this._customBtn = shadowRoot.querySelector('#mzta-custom_btn'); + this._customStep = shadowRoot.querySelector('#mzta-custom_step'); this._customBtn.addEventListener("click", () => { this._customTextBtnClick({customBtn:this._customBtn,customLoading:this._customLoading,customDiv:this._customText}) }); this._customTextArea.addEventListener("keydown", (event) => { if(event.code == "Enter" && event.ctrlKey) this._customTextBtnClick({customBtn:this._customBtn,customLoading:this._customLoading,customDiv:this._customText}) }); } @@ -340,6 +351,13 @@ class MessageInput extends HTMLElement { infoSpan.textContent = "[" + browser.i18n.getMessage("customPrompts_form_label_ID") + ": " + currentItem.info + "]"; infoDiv.appendChild(infoSpan); } + + if(this._customTextArray.length > 1) { + this._customStep.textContent = (this._currentCustomTextIndex + 1) + "/" + this._customTextArray.length; + this._customStep.style.display = 'block'; + } else { + this._customStep.style.display = 'none'; + } this._customTextArea.focus(); } From d00e2425096cf1cd248756540a517ca0f933fcb6 Mon Sep 17 00:00:00 2001 From: mic Date: Thu, 12 Feb 2026 22:41:16 +0100 Subject: [PATCH 12/16] button margin added. see #525 #554 --- api_webchat/messageInput.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/api_webchat/messageInput.js b/api_webchat/messageInput.js index 1e226c15..3ebdd8c7 100644 --- a/api_webchat/messageInput.js +++ b/api_webchat/messageInput.js @@ -115,6 +115,9 @@ messagesInputStyle.textContent = ` font-size: 12px; color: #ccc; } + #mzta-custom_btn{ + margin-top:7px; + } @media (prefers-color-scheme: dark) { #messageInputField { background-color: #303030; From 12206f05573bc76dccb2868064959cb4bc2c3556 Mon Sep 17 00:00:00 2001 From: mic Date: Thu, 12 Feb 2026 22:46:50 +0100 Subject: [PATCH 13/16] submit additional_text when pressing enter. see #525 fixes #654 --- api_webchat/messageInput.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/api_webchat/messageInput.js b/api_webchat/messageInput.js index 3ebdd8c7..aebc2584 100644 --- a/api_webchat/messageInput.js +++ b/api_webchat/messageInput.js @@ -238,7 +238,12 @@ class MessageInput extends HTMLElement { this._customBtn = shadowRoot.querySelector('#mzta-custom_btn'); this._customStep = shadowRoot.querySelector('#mzta-custom_step'); this._customBtn.addEventListener("click", () => { this._customTextBtnClick({customBtn:this._customBtn,customLoading:this._customLoading,customDiv:this._customText}) }); - this._customTextArea.addEventListener("keydown", (event) => { if(event.code == "Enter" && event.ctrlKey) this._customTextBtnClick({customBtn:this._customBtn,customLoading:this._customLoading,customDiv:this._customText}) }); + this._customTextArea.addEventListener("keydown", (event) => { + if (event.key === "Enter" && !event.shiftKey) { + event.preventDefault(); + this._customTextBtnClick({customBtn:this._customBtn,customLoading:this._customLoading,customDiv:this._customText}); + } + }); } connectedCallback() { From 0740d94c796e789b5c68fbbdf8005d29fd134074 Mon Sep 17 00:00:00 2001 From: mic Date: Thu, 12 Feb 2026 22:49:30 +0100 Subject: [PATCH 14/16] focus on the additional_text textarea. see #525 --- api_webchat/messageInput.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api_webchat/messageInput.js b/api_webchat/messageInput.js index aebc2584..2907174f 100644 --- a/api_webchat/messageInput.js +++ b/api_webchat/messageInput.js @@ -342,8 +342,8 @@ class MessageInput extends HTMLElement { this._customTextArray.push({ placeholder: "{%additional_text%}", info: "" }); } this._currentCustomTextIndex = 0; - this._renderCustomTextStep(); this._customText.style.display = 'block'; + this._renderCustomTextStep(); } _renderCustomTextStep() { From 0ac6ae6650e2965ca0587c0db8f98bcc9609b631 Mon Sep 17 00:00:00 2001 From: mic Date: Sat, 14 Feb 2026 23:01:20 +0100 Subject: [PATCH 15/16] custom_text_array initialize fixed. see #525 --- js/mzta-menus.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/mzta-menus.js b/js/mzta-menus.js index b29ad6cc..cecfa413 100644 --- a/js/mzta-menus.js +++ b/js/mzta-menus.js @@ -193,7 +193,7 @@ export class mzta_Menus { tags_full_list: tags_full_list }); - curr_prompt.custom_text_array = {}; + curr_prompt.custom_text_array = []; if(placeholdersUtils.hasPlaceholder(curr_prompt.text, 'additional_text')){ curr_prompt.custom_text_array = placeholdersUtils.getPlaceholdersAdditionalTextArray(curr_prompt.text); From d5d11e3c0c16024279250b8a7ecedda7a4e43e97 Mon Sep 17 00:00:00 2001 From: mic Date: Sat, 14 Feb 2026 23:04:08 +0100 Subject: [PATCH 16/16] customDiv with multiple additional_text also when using the chatgpt web interface integration. see #525 #650 --- js/mzta-chatgpt.js | 93 +++++++++++++++++++++++++++++++++++++--------- mzta-background.js | 2 +- 2 files changed, 77 insertions(+), 18 deletions(-) diff --git a/js/mzta-chatgpt.js b/js/mzta-chatgpt.js index eeda649e..3ff3a440 100644 --- a/js/mzta-chatgpt.js +++ b/js/mzta-chatgpt.js @@ -30,6 +30,8 @@ let current_mailMessageId = null; let selectionChangeTimeout = null; let isDragging = false; let delay_wait_completion = 7000; // milliseconds +let _customTextArray = []; +let _currentCustomTextIndex = 0; async function chatgpt_sendMsg(msg, method ='') { // return -1 send button not found, -2 textarea not found let textArea = document.getElementById('prompt-textarea') @@ -125,6 +127,8 @@ function addCustomDiv(prompt_action,tabId,mailMessageId) { style.textContent += "#mzta-custom_loading{height:50px;display:none;}"; style.textContent += "#mzta-custom_textarea{color:black;padding:1px;font-size:15px;width:100%;}"; style.textContent += "#mzta-custom_info{text-align:center;width:100%;padding-bottom:10px;font-size:15px;}"; + style.textContent += "#mzta-custom_info span{font-size:0.8em;}"; + style.textContent += "#mzta-custom_step{position: absolute;bottom: 5px;right: 10px;font-size: 12px;color: #ccc;}"; style.textContent += "#mzta-prompt-name{font-size:13px;font-style:italic;color:#919191;position:fixed;bottom:75px;;left:0;padding-left:5px;}"; style.textContent += "#mzta-diff-overlay{position: fixed;top:0;left:0;width:100vw;height:100vh;background: rgba(0, 0, 0, 0.5);display:flex;justify-content:center;align-items:center;z-index:999;}"; style.textContent += "#mzta-diff{padding:10px;border:2px solid white;border-radius:1em;position:fixed;top:50%;left:50%;width:80%;height:30em;transform:translate(-50%,-50%);z-index:9999;background-color: #333;color: white;}"; @@ -365,6 +369,7 @@ function addCustomDiv(prompt_action,tabId,mailMessageId) { customDiv.appendChild(customInfo); let customTextArea = document.createElement('textarea'); customTextArea.id = 'mzta-custom_textarea'; + customTextArea.rows = 5; customDiv.appendChild(customTextArea); let customLoading = document.createElement('img'); customLoading.src = browser.runtime.getURL("/images/loading.gif"); @@ -377,6 +382,9 @@ function addCustomDiv(prompt_action,tabId,mailMessageId) { customBtn.addEventListener("click", () => { customTextBtnClick({customBtn:customBtn,customLoading:customLoading,customDiv:customDiv}) }); customTextArea.addEventListener("keydown", (event) => { if(event.code == "Enter" && event.ctrlKey) customTextBtnClick({customBtn:customBtn,customLoading:customLoading,customDiv:customDiv}) }); customDiv.appendChild(customBtn); + let customStep = document.createElement('div'); + customStep.id = 'mzta-custom_step'; + customDiv.appendChild(customStep); fixedDiv.appendChild(customDiv); // light background hint with diagonal thick arrow @@ -453,14 +461,54 @@ function createReplyToAllIcon() { return svg; } +function renderCustomTextStep() { + const currentItem = _customTextArray[_currentCustomTextIndex]; + const infoDiv = document.getElementById('mzta-custom_info'); + const customTextArea = document.getElementById('mzta-custom_textarea'); + const customStep = document.getElementById('mzta-custom_step'); + + customTextArea.value = ""; + infoDiv.textContent = browser.i18n.getMessage("chatgpt_win_custom_text"); + + if (currentItem.info && currentItem.info.trim() !== "") { + infoDiv.appendChild(document.createElement("br")); + const infoSpan = document.createElement("span"); + infoSpan.textContent = "[" + browser.i18n.getMessage("customPrompts_form_label_ID") + ": " + currentItem.info + "]"; + infoDiv.appendChild(infoSpan); + } + + if(_customTextArray.length > 1) { + customStep.textContent = (_currentCustomTextIndex + 1) + "/" + _customTextArray.length; + customStep.style.display = 'block'; + } else { + customStep.style.display = 'none'; + } + + customTextArea.focus(); +} + function customTextBtnClick(args) { const customText = document.getElementById('mzta-custom_textarea').value; - args.customBtn.disabled = true; - args.customBtn.classList.add('disabled'); - args.customLoading.style.display = 'inline-block'; - args.customLoading.style.display = 'none'; - doProceed(current_message,customText); - args.customDiv.style.display = 'none'; + + if (_customTextArray[_currentCustomTextIndex]) { + _customTextArray[_currentCustomTextIndex].custom_text = customText; + } + + _currentCustomTextIndex++; + + if (_currentCustomTextIndex < _customTextArray.length) { + renderCustomTextStep(); + } else { + args.customBtn.disabled = true; + args.customBtn.classList.add('disabled'); + args.customLoading.style.display = 'inline-block'; + args.customLoading.style.display = 'none'; + doProceed(current_message, _customTextArray); + args.customDiv.style.display = 'none'; + + args.customBtn.disabled = false; + args.customBtn.classList.remove('disabled'); + } } function checkGPTModel(model) { @@ -534,8 +582,14 @@ function checkLoggedIn(){ } function showCustomTextField(){ + let rawArray = current_message.prompt_info?.custom_text_array; + _customTextArray = Array.isArray(rawArray) ? rawArray : []; + if (_customTextArray.length === 0) { + _customTextArray.push({ placeholder: "{%additional_text%}", info: "" }); + } + _currentCustomTextIndex = 0; document.getElementById('mzta-custom_text').style.display = 'block'; - document.getElementById('mzta-custom_textarea').focus(); + renderCustomTextStep(); } async function doProceed(message, customText = ''){ @@ -545,16 +599,21 @@ async function doProceed(message, customText = ''){ await checkGPTModel(_gpt_model); } let final_prompt = message.prompt; -// console.log(">>>>>>>>>>>> doProceed customText: " + customText); -// console.log(">>>>>>>>>>>> doProceed final_prompt: " + final_prompt); -// console.log(">>>>>>>>>>>> doProceed mztaPhDefVal: " + JSON.stringify(mztaPhDefVal)); - //check if there is the additional_text placeholder - if(final_prompt.includes('{%additional_text%}')){ - // console.log(">>>>>>>>>>>> found ph customText: " + customText); - final_prompt = final_prompt.replace('{%additional_text%}', customText || (mztaPhDefVal == '1'?'':'{%additional_text%}')); - }else{ - if(customText != ''){ - final_prompt += ' '+customText; + + if (Array.isArray(customText)) { + customText.forEach(obj => { + let escapedPH = obj.placeholder.replace(/[.*+?^{$}()|[\\]\\\\]/g, '\\\\$&'); + let regex = new RegExp(escapedPH, 'g'); + final_prompt = final_prompt.replace(regex, obj.custom_text); + }); + } else { + //check if there is the additional_text placeholder + if(final_prompt.includes('{%additional_text%}')){ + final_prompt = final_prompt.replace('{%additional_text%}', customText || (mztaPhDefVal == '1'?'':'{%additional_text%}')); + }else{ + if(customText != ''){ + final_prompt += ' '+customText; + } } } diff --git a/mzta-background.js b/mzta-background.js index b0eb1f13..ea2473fd 100644 --- a/mzta-background.js +++ b/mzta-background.js @@ -515,7 +515,7 @@ async function openChatGPT(promptText, action, curr_tabId, prompt_name = '', do_ let mailMessageId = -1; if(mailMessage) mailMessageId = mailMessage.id; promptText = convertNewlinesToParagraphs(promptText); - browser.tabs.sendMessage(createdTab.id, { command: "chatgpt_send", prompt: promptText, action: action, tabId: curr_tabId, mailMessageId: mailMessageId}); + browser.tabs.sendMessage(createdTab.id, { command: "chatgpt_send", prompt: promptText, action: action, tabId: curr_tabId, mailMessageId: mailMessageId, prompt_info: prompt_info}); taLog.log('[ChatGPT Web] Connection succeded!'); taLog.log("[ThunderAI] ChatGPT Web script injected successfully"); browser.runtime.onMessage.removeListener(listener);