diff --git a/api_webchat/index.html b/api_webchat/index.html index 7989868d..5d803548 100644 --- a/api_webchat/index.html +++ b/api_webchat/index.html @@ -17,6 +17,7 @@ + diff --git a/api_webchat/messagesArea.js b/api_webchat/messagesArea.js index 9b1b2d98..c4888060 100644 --- a/api_webchat/messagesArea.js +++ b/api_webchat/messagesArea.js @@ -90,6 +90,17 @@ messagesAreaStyle.textContent = ` color: navy; margin-bottom: var(--margin); } + /* diff viewer */ + .added { + background-color: #d4fcdc; + display: inline; + } + + .removed { + background-color: #fddddd; + display: inline; + text-decoration: line-through; + } `; messagesAreaTemplate.content.appendChild(messagesAreaStyle); @@ -207,27 +218,6 @@ class MessagesArea extends HTMLElement { } addActionButtons(promptData = null) { - // ============================== TESTING - // promptData = { - // action: "1", - // tabId: 1, - // mailMessageId: 1 - // } - // let browser = { - // i18n: { - // getMessage: async function(key) { - // return key; - // } - // }, - // storage: { - // sync: { - // get: async function(key) { - // return 'apitest'; - // } - // } - // } - // } - // ============================== TESTING - END if(promptData == null) { return; } const actionButtons = document.createElement('div'); actionButtons.classList.add('action-buttons'); @@ -257,6 +247,18 @@ class MessagesArea extends HTMLElement { browser.runtime.sendMessage({command: "chatgpt_close", window_id: (await browser.windows.getCurrent()).id}); // close window }); if(promptData.action != 0) { actionButtons.appendChild(actionButton); } + + // diff viewer button + if(promptData.prompt_info?.use_diff_viewer == "1") { + const diffvButton = document.createElement('button'); + diffvButton.textContent = 'Show differences'; + diffvButton.addEventListener('click', async () => { + let strippedText = fullTextHTMLAtAssignment.replace(/<\/?[^>]+(>|$)/g, ""); + this.appendDiffViewer(promptData.prompt_info?.selection_text, strippedText); + }); + actionButtons.appendChild(diffvButton); + } + actionButtons.appendChild(closeButton); this.messages.appendChild(actionButtons); this.scrollToBottom(); @@ -268,6 +270,40 @@ class MessagesArea extends HTMLElement { this.scrollToBottom(); } + appendDiffViewer(originalText, newText) { + const wordDiff = Diff.diffWords(originalText, newText); + + const messageElement = document.createElement('div'); + messageElement.classList.add('message', 'bot'); + + // Iterate over each part of the diff to create the HTML output + wordDiff.forEach(part => { + const diffElement = document.createElement("span"); + + // Apply a different class depending on whether the word is added, removed, or unchanged + if (part.added) { + diffElement.className = "added"; + diffElement.textContent = part.value; + } else if (part.removed) { + diffElement.className = "removed"; + diffElement.textContent = part.value; + } else { + diffElement.textContent = part.value; + } + + // Add the element to the container + messageElement.appendChild(diffElement); + }); + + const header = document.createElement('h2'); + header.textContent = "Diff viewer"; + this.messages.appendChild(header); + + this.messages.appendChild(messageElement); + this.addDivider(); + this.scrollToBottom(); + } + flushAccumulatingMessage() { if (this.accumulatingMessageEl) { // Collect all tokens in a full text diff --git a/js/mzta-menus.js b/js/mzta-menus.js index 36f236cd..03b53868 100644 --- a/js/mzta-menus.js +++ b/js/mzta-menus.js @@ -106,7 +106,9 @@ export class mzta_Menus { let selection_text = ''; let only_typed_text = ''; selection_text = msg_text.selection.replace(/\s+/g, ' ').trim(); + curr_prompt.selection_text = selection_text; body_text = msg_text.text.replace(/\s+/g, ' ').trim(); + curr_prompt.body_text = body_text; only_typed_text = msg_text.only_typed_text.replace(/\s+/g, ' ').trim(); //open chatgpt window //console.log("Click menu item..."); @@ -260,7 +262,7 @@ export class mzta_Menus { break; } }else{ // Classic prompts for the API webchat - this.openChatGPT(fullPrompt, curr_prompt.action, tabs[0].id, curr_prompt.name, curr_prompt.need_custom_text); + this.openChatGPT(fullPrompt, curr_prompt.action, tabs[0].id, curr_prompt.name, curr_prompt.need_custom_text, curr_prompt); taWorkingStatus.stopWorking(); return {ok:'1'}; } diff --git a/mzta-background.js b/mzta-background.js index e51417fe..835b3de7 100644 --- a/mzta-background.js +++ b/mzta-background.js @@ -296,7 +296,7 @@ browser.runtime.onMessageExternal.addListener((message, sender, sendResponse) => } }); -async function openChatGPT(promptText, action, curr_tabId, prompt_name = '', do_custom_text = 0) { +async function openChatGPT(promptText, action, curr_tabId, prompt_name = '', do_custom_text = 0, prompt_info = {}) { let prefs = await browser.storage.sync.get(prefs_default); taLog.changeDebug(prefs.do_debug); prefs = checkScreenDimensions(prefs); @@ -405,7 +405,7 @@ async function openChatGPT(promptText, action, curr_tabId, prompt_name = '', do_ return; } //console.log(">>>>>>>>>> sender: " + JSON.stringify(sender)); - browser.tabs.sendMessage(createdTab.id, { command: "api_send", prompt: promptText, action: action, tabId: curr_tabId, mailMessageId: mailMessageId2, do_custom_text: do_custom_text}); + browser.tabs.sendMessage(createdTab.id, { command: "api_send", prompt: promptText, action: action, tabId: curr_tabId, mailMessageId: mailMessageId2, do_custom_text: do_custom_text, prompt_info: prompt_info}); taLog.log('[OpenAI ChatGPT] Connection succeded!'); browser.runtime.onMessage.removeListener(listener2); } @@ -455,7 +455,7 @@ async function openChatGPT(promptText, action, curr_tabId, prompt_name = '', do_ return; } //console.log(">>>>>>>>>> sender: " + JSON.stringify(sender)); - browser.tabs.sendMessage(createdTab.id, { command: "api_send", prompt: promptText, action: action, tabId: curr_tabId, mailMessageId: mailMessageId5, do_custom_text: do_custom_text}); + browser.tabs.sendMessage(createdTab.id, { command: "api_send", prompt: promptText, action: action, tabId: curr_tabId, mailMessageId: mailMessageId5, do_custom_text: do_custom_text, prompt_info: prompt_info}); taLog.log('[Google Gemini] Connection succeded!'); browser.runtime.onMessage.removeListener(listener5); } @@ -511,7 +511,7 @@ async function openChatGPT(promptText, action, curr_tabId, prompt_name = '', do_ browser.tabs.sendMessage(createdTab3.id, { command: "api_error", error: browser.i18n.getMessage('ollama_empty_model')}); return; } - browser.tabs.sendMessage(createdTab3.id, { command: "api_send", prompt: promptText, action: action, tabId: curr_tabId, mailMessageId: mailMessageId3, do_custom_text: do_custom_text}); + browser.tabs.sendMessage(createdTab3.id, { command: "api_send", prompt: promptText, action: action, tabId: curr_tabId, mailMessageId: mailMessageId3, do_custom_text: do_custom_text, prompt_info: prompt_info}); taLog.log('[Ollama API] Connection succeded!'); browser.runtime.onMessage.removeListener(listener3); } @@ -563,7 +563,7 @@ async function openChatGPT(promptText, action, curr_tabId, prompt_name = '', do_ return; } - browser.tabs.sendMessage(createdTab.id, { command: "api_send", prompt: promptText, action: action, tabId: curr_tabId, mailMessageId: mailMessageId4, do_custom_text: do_custom_text}); + browser.tabs.sendMessage(createdTab.id, { command: "api_send", prompt: promptText, action: action, tabId: curr_tabId, mailMessageId: mailMessageId4, do_custom_text: do_custom_text, prompt_info: prompt_info}); taLog.log('[OpenAI Comp API] Connection succeded!'); browser.runtime.onMessage.removeListener(listener4); }