let originTabId = null; // Create context menu chrome.runtime.onInstalled.addListener(() => { chrome.contextMenus.create({ id: "improveMail", title: "Verbessere Mail", contexts: ["selection"], // Show only when text is selected }); chrome.contextMenus.create({ id: "improveText", title: "Verbessere Text", contexts: ["selection"], // Show only when text is selected }); chrome.contextMenus.create({ id: "seoText", title: "Erstelle ein SEO-Text", contexts: ["selection"], // Show only when text is selected }); chrome.contextMenus.create({ id: "explainMe", title: "Erkläre Text", contexts: ["selection"], // Show only when text is selected }); }); // Utility function to handle menu item click dynamically function handleMenuItemClick(info, tab, prefixText) { originTabId = tab.id; if (info.selectionText) { const selectedText = prefixText + info.selectionText; chrome.tabs.create({ url: "https://chatgpt.com/?temporary-chat=true" }, (newTab) => { chrome.tabs.onUpdated.addListener(function listener(tabId, info) { if (tabId === newTab.id && info.status === "complete") { chrome.tabs.onUpdated.removeListener(listener); chrome.scripting.executeScript({ target: { tabId: newTab.id }, func: pasteToChatGPT, args: [selectedText, newTab.id], }); } }); }); } } // Handle context menu clicks chrome.contextMenus.onClicked.addListener((info, tab) => { const menuActions = { explainMe: 'Erkläre mir folgenden Text, fasse es kurz und gut lesbar zusammen. Erstelle keine eigenen Kommentare, zeige rein nur den text als Ausgabe: ', improveMail: 'Verbessere folgende Mail, erstelle keine eigenen Kommentare, zeige rein nur den text als ausgabe: ', improveText: 'Verbessere folgenden Text, mach es nicht viel länger oder kürzer als es jetzt schon ist, erstelle keine eigenen Kommentare, zeige rein nur den text als Ausgabe: ', seoText: 'Du bist der Weltbeste SEO-Text Author. Schreibe einen SEO-optimierten Text mit 400-500 Wörtern basierend auf dem folgenden Inhalt. Identifiziere das Haupt-Keyword und integriere es mit einer Keyword-Dichte von 2-3 %. Strukturierte den Text mit HTML-Elementen (h1, h2, h3, p). Hebe das Keyword mit dem strong-Tag hervor. Gib nur den HTML-Code aus, ohne HTML-, Head- oder Body-Tags und ohne Kommentare. Die Ausgabe sollte als reiner Text erscheinen, nicht in einem Codefeld. Hier ist der relevante Text/Keyword: ', }; if (menuActions[info.menuItemId]) { handleMenuItemClick(info, tab, menuActions[info.menuItemId]); } }); // Listen for a message to close the current tab and switch back chrome.runtime.onMessage.addListener((message, sender) => { if (message.action === "closeGPTAndSwitchBack") { const currentTabId = sender.tab.id; // Close the current tab chrome.tabs.remove(currentTabId, () => { console.log("Closed current tab:", currentTabId); // Switch back to the original tab if (originTabId) { chrome.tabs.update(originTabId, { active: true }); } }); } }); // Function to paste text into ChatGPT input and send it function pasteToChatGPT(text, gptTab) { const newChatButton = document.querySelector('a[href="/"]'); if (newChatButton) newChatButton.click(); let sendInterval; const interval = setInterval(() => { const contentEditableDiv = document.querySelector('div[contenteditable="true"]'); if (contentEditableDiv) { clearInterval(interval); // Stop retrying once the div is found // Insert text into the contenteditable div contentEditableDiv.innerHTML = `

${text}

`; // Dispatch input events to trigger the mirroring mechanism contentEditableDiv.dispatchEvent(new Event('input', { bubbles: true })); sendInterval = setInterval(() => { // Simulate clicking the Send button const sendButton = document.querySelector('button[data-testid="send-button"]'); if (sendButton) { clearInterval(sendInterval); sendButton.click(); function fallbackCopyTextToClipboard(text) { const textArea = document.createElement("textarea"); textArea.value = text; textArea.style.position = "fixed"; // Prevent scrolling document.body.appendChild(textArea); textArea.focus(); textArea.select(); try { const successful = document.execCommand('copy'); console.log(successful ? "Fallback: Copied to clipboard!" : "Fallback: Failed to copy!"); } catch (err) { console.error("Fallback: Could not copy text:", err); } document.body.removeChild(textArea); } function waitForElement(selector, checkForDisappearance = false) { return new Promise((resolve) => { const observer = new MutationObserver(() => { const element = document.querySelector(selector); if ((element && !checkForDisappearance) || (!element && checkForDisappearance)) { observer.disconnect(); resolve(element); } }); observer.observe(document.body, { childList: true, subtree: true }); }); } // Function to copy text to the clipboard with fallback function copyTextToClipboard(text) { function fallbackCopyTextToClipboard(text) { const textArea = document.createElement("textarea"); textArea.value = text.trim(); // Ensure plain text without leading/trailing whitespace textArea.style.position = "fixed"; // Prevent scrolling document.body.appendChild(textArea); textArea.focus(); textArea.select(); try { const successful = document.execCommand("copy"); console.log(successful ? "Fallback: Copied to clipboard!" : "Fallback: Failed to copy!"); } catch (err) { console.error("Fallback: Could not copy text:", err); } document.body.removeChild(textArea); } if (navigator.clipboard && document.hasFocus()) { navigator.clipboard.writeText(text.trim()) .then(() => console.log("Copied to clipboard!")) .catch((err) => { console.error("Clipboard API failed, falling back:", err); fallbackCopyTextToClipboard(text); }); } else { fallbackCopyTextToClipboard(text); } } waitForElement('button[data-testid="stop-button"]').then(() => { return new Promise((resolve) => { const observer = new MutationObserver(() => { const stopButton = document.querySelector('button[data-testid="stop-button"]'); if (!stopButton) { observer.disconnect(); setTimeout(() => { resolve(); }, 1500); } }); observer.observe(document.body, { childList: true, subtree: true }); }); }).then(() => { const assistantMessages = document.querySelectorAll('div[data-message-author-role="assistant"]'); const latestResponse = assistantMessages[assistantMessages.length - 1]?.innerText || ""; if (latestResponse) { setTimeout(() => { copyTextToClipboard(latestResponse) console.log("Action complete. Closing tab..."); chrome.runtime.sendMessage({ action: "closeGPTAndSwitchBack" }); }, 1000); } }); } else { console.error("Send button not found!"); } }, 100); // Check every 100ms } }, 100); // Check every 100ms let timeout = setTimeout(() => { clearInterval(interval); clearInterval(sendInterval); }, 5000); }