diff --git a/src/content_script.js b/src/content_script.js index 2c6104e..4de772e 100644 --- a/src/content_script.js +++ b/src/content_script.js @@ -1,58 +1,60 @@ const buttonOuterHTMLFallback = ``; -async function init() { + +async function init () { if (window.buttonsInterval) { clearInterval(window.buttonsInterval); } window.buttonsInterval = setInterval(() => { - const actionsArea = document.querySelector("form>div>div"); + const actionsArea = document.querySelector('form>div>div'); if (!actionsArea) { return; } if (shouldAddButtons(actionsArea)) { - let TryAgainButton = actionsArea.querySelector("button"); + let TryAgainButton = actionsArea.querySelector('button'); if (!TryAgainButton) { - const parentNode = document.createElement("div"); + const parentNode = document.createElement('div'); parentNode.innerHTML = buttonOuterHTMLFallback; - TryAgainButton = parentNode.querySelector("button"); + TryAgainButton = parentNode.querySelector('button'); } addActionsButtons(actionsArea, TryAgainButton); - } else if(shouldRemoveButtons()){ + } + else if (shouldRemoveButtons()) { removeButtons(); } - }, 200); + }, 3000); } -function shouldRemoveButtons() { - const isOpenScreen = document.querySelector("h1.text-4xl"); - if(isOpenScreen){ +function shouldRemoveButtons () { + const isOpenScreen = document.querySelector('h1.text-4xl'); + if (isOpenScreen) { return true; } - const inConversation = document.querySelector("form button>div"); - if(inConversation){ + const inConversation = document.querySelector('form button>div'); + if (!inConversation) { return true; } return false; } -function shouldAddButtons(actionsArea) { +function shouldAddButtons (actionsArea) { // first, check if there's a "Try Again" button and no other buttons - const buttons = actionsArea.querySelectorAll("button"); + const buttons = actionsArea.querySelectorAll('button'); const hasTryAgainButton = Array.from(buttons).some((button) => { - return !button.id?.includes("download"); + return !button.id?.includes('download'); }); if (hasTryAgainButton && buttons.length === 1) { return true; } // otherwise, check if open screen is not visible - const isOpenScreen = document.querySelector("h1.text-4xl"); + const isOpenScreen = document.querySelector('h1.text-4xl'); if (isOpenScreen) { return false; } // check if the conversation is finished and there are no share buttons - const finishedConversation = document.querySelector("form button>svg"); - const hasShareButtons = actionsArea.querySelectorAll("button[share-ext]"); + const finishedConversation = document.querySelector('form button>svg'); + const hasShareButtons = actionsArea.querySelectorAll('button[share-ext]'); if (finishedConversation && !hasShareButtons.length) { return true; } @@ -61,14 +63,14 @@ function shouldAddButtons(actionsArea) { } const Format = { - PNG: "png", - PDF: "pdf", + PNG: 'png', + PDF: 'pdf', }; -function removeButtons() { - const downloadButton = document.getElementById("download-png-button"); - const downloadPdfButton = document.getElementById("download-pdf-button"); - const downloadHtmlButton = document.getElementById("download-html-button"); +function removeButtons () { + const downloadButton = document.getElementById('download-png-button'); + const downloadPdfButton = document.getElementById('download-pdf-button'); + const downloadHtmlButton = document.getElementById('download-html-button'); if (downloadButton) { downloadButton.remove(); } @@ -80,34 +82,34 @@ function removeButtons() { } } -function addActionsButtons(actionsArea, TryAgainButton) { +function addActionsButtons (actionsArea, TryAgainButton) { const downloadButton = TryAgainButton.cloneNode(true); - downloadButton.id = "download-png-button"; - downloadButton.setAttribute("share-ext", "true"); - downloadButton.innerText = "Generate PNG"; + downloadButton.id = 'download-png-button'; + downloadButton.setAttribute('share-ext', 'true'); + downloadButton.innerText = 'Generate PNG'; downloadButton.onclick = () => { downloadThread(); }; actionsArea.appendChild(downloadButton); const downloadPdfButton = TryAgainButton.cloneNode(true); - downloadPdfButton.id = "download-pdf-button"; - downloadButton.setAttribute("share-ext", "true"); - downloadPdfButton.innerText = "Download PDF"; + downloadPdfButton.id = 'download-pdf-button'; + downloadButton.setAttribute('share-ext', 'true'); + downloadPdfButton.innerText = 'Download PDF'; downloadPdfButton.onclick = () => { - downloadThread({ as: Format.PDF }); + downloadThread({as: Format.PDF}); }; actionsArea.appendChild(downloadPdfButton); const exportHtml = TryAgainButton.cloneNode(true); - exportHtml.id = "download-html-button"; - downloadButton.setAttribute("share-ext", "true"); - exportHtml.innerText = "Share Link"; + exportHtml.id = 'download-html-button'; + downloadButton.setAttribute('share-ext', 'true'); + exportHtml.innerText = 'Share Link'; exportHtml.onclick = () => { sendRequest(); }; actionsArea.appendChild(exportHtml); } -function downloadThread({ as = Format.PNG } = {}) { +function downloadThread ({as = Format.PNG} = {}) { const elements = new Elements(); elements.fixLocation(); const pixelRatio = window.devicePixelRatio; @@ -119,27 +121,28 @@ function downloadThread({ as = Format.PNG } = {}) { }).then(async function (canvas) { elements.restoreLocation(); window.devicePixelRatio = pixelRatio; - const imgData = canvas.toDataURL("image/png"); + const imgData = canvas.toDataURL('image/png'); requestAnimationFrame(() => { if (as === Format.PDF) { return handlePdf(imgData, canvas, pixelRatio); - } else { + } + else { handleImg(imgData); } }); }); } -function handleImg(imgData) { - const binaryData = atob(imgData.split("base64,")[1]); +function handleImg (imgData) { + const binaryData = atob(imgData.split('base64,')[1]); const data = []; for (let i = 0; i < binaryData.length; i++) { data.push(binaryData.charCodeAt(i)); } - const blob = new Blob([new Uint8Array(data)], { type: "image/png" }); + const blob = new Blob([new Uint8Array(data)], {type: 'image/png'}); const url = URL.createObjectURL(blob); - window.open(url, "_blank"); + window.open(url, '_blank'); // const a = document.createElement("a"); // a.href = url; @@ -147,17 +150,17 @@ function handleImg(imgData) { // a.click(); } -function handlePdf(imgData, canvas, pixelRatio) { - const { jsPDF } = window.jspdf; - const orientation = canvas.width > canvas.height ? "l" : "p"; - var pdf = new jsPDF(orientation, "pt", [ +function handlePdf (imgData, canvas, pixelRatio) { + const {jsPDF} = window.jspdf; + const orientation = canvas.width > canvas.height ? 'l' : 'p'; + var pdf = new jsPDF(orientation, 'pt', [ canvas.width / pixelRatio, canvas.height / pixelRatio, ]); var pdfWidth = pdf.internal.pageSize.getWidth(); var pdfHeight = pdf.internal.pageSize.getHeight(); - pdf.addImage(imgData, "PNG", 0, 0, pdfWidth, pdfHeight); - pdf.save("chat-gpt.pdf"); + pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight); + pdf.save('chat-gpt.pdf'); } // async function getWidthHeightFromBase64(base64Img) { @@ -175,114 +178,114 @@ function handlePdf(imgData, canvas, pixelRatio) { // } class Elements { - constructor() { + constructor () { this.init(); } - init() { + + init () { // this.threadWrapper = document.querySelector(".cdfdFe"); - this.spacer = document.querySelector(".w-full.h-48.flex-shrink-0"); + this.spacer = document.querySelector('.w-full.h-48.flex-shrink-0'); this.thread = document.querySelector( - "[class*='react-scroll-to-bottom']>[class*='react-scroll-to-bottom']>div" + '[class*=\'react-scroll-to-bottom\']>[class*=\'react-scroll-to-bottom\']>div', ); - this.positionForm = document.querySelector("form").parentNode; + this.positionForm = document.querySelector('form').parentNode; // this.styledThread = document.querySelector("main"); // this.threadContent = document.querySelector(".gAnhyd"); this.scroller = Array.from( - document.querySelectorAll('[class*="react-scroll-to"]') - ).filter((el) => el.classList.contains("h-full"))[0]; - this.hiddens = Array.from(document.querySelectorAll(".overflow-hidden")); - this.images = Array.from(document.querySelectorAll("img[srcset]")); + document.querySelectorAll('[class*="react-scroll-to"]'), + ).filter((el) => el.classList.contains('h-full'))[0]; + this.hiddens = Array.from(document.querySelectorAll('.overflow-hidden')); + this.images = Array.from(document.querySelectorAll('img[srcset]')); } - fixLocation() { + + fixLocation () { this.hiddens.forEach((el) => { - el.classList.remove("overflow-hidden"); + el.classList.remove('overflow-hidden'); }); - this.spacer.style.display = "none"; - this.thread.style.maxWidth = "960px"; - this.thread.style.marginInline = "auto"; - this.positionForm.style.display = "none"; - this.scroller.classList.remove("h-full"); - this.scroller.style.minHeight = "100vh"; + this.spacer.style.display = 'none'; + this.thread.style.maxWidth = '960px'; + this.thread.style.marginInline = 'auto'; + this.positionForm.style.display = 'none'; + this.scroller.classList.remove('h-full'); + this.scroller.style.minHeight = '100vh'; this.images.forEach((img) => { - const srcset = img.getAttribute("srcset"); - img.setAttribute("srcset_old", srcset); - img.setAttribute("srcset", ""); + const srcset = img.getAttribute('srcset'); + img.setAttribute('srcset_old', srcset); + img.setAttribute('srcset', ''); }); //Fix to the text shifting down when generating the canvas - document.body.style.lineHeight = "0.5"; + document.body.style.lineHeight = '0.5'; } - restoreLocation() { + + restoreLocation () { this.hiddens.forEach((el) => { - el.classList.add("overflow-hidden"); + el.classList.add('overflow-hidden'); }); this.spacer.style.display = null; this.thread.style.maxWidth = null; this.thread.style.marginInline = null; this.positionForm.style.display = null; - this.scroller.classList.add("h-full"); + this.scroller.classList.add('h-full'); this.scroller.style.minHeight = null; this.images.forEach((img) => { - const srcset = img.getAttribute("srcset_old"); - img.setAttribute("srcset", srcset); - img.setAttribute("srcset_old", ""); + const srcset = img.getAttribute('srcset_old'); + img.setAttribute('srcset', srcset); + img.setAttribute('srcset_old', ''); }); document.body.style.lineHeight = null; } } -function selectElementByClassPrefix(classPrefix) { +function selectElementByClassPrefix (classPrefix) { const element = document.querySelector(`[class^='${classPrefix}']`); return element; } -async function sendRequest() { +async function sendRequest () { const data = getData(); const uploadUrlResponse = await fetch( - "https://chatgpt-static.s3.amazonaws.com/url.txt" + 'https://chatgpt-static.s3.amazonaws.com/url.txt', ); const uploadUrl = await uploadUrlResponse.text(); fetch(uploadUrl, { - method: "POST", + method: 'POST', headers: { - "Content-Type": "application/json", + 'Content-Type': 'application/json', }, body: JSON.stringify(data), - }) - .then((response) => response.json()) - .then((data) => { - window.open(data.url, "_blank"); - }); + }).then((response) => response.json()).then((data) => { + window.open(data.url, '_blank'); + }); } -function getData() { - const globalCss = getCssFromSheet( - document.querySelector("link[rel=stylesheet]").sheet - ); - const localCss = - getCssFromSheet( - document.querySelector(`style[data-styled][data-styled-version]`).sheet - ) || "body{}"; +function getData () { + // const globalCss = getCssFromSheet( + // document.querySelector("link[rel=stylesheet]").sheet + // ); + const globalStylesheet = document.querySelector('link[rel=stylesheet]'); + const globalCss = globalStylesheet ? getCssFromSheet(globalStylesheet.sheet) : ''; + const stylesheet = document.querySelector(`style[data-styled][data-styled-version]`); + const localCss = stylesheet ? getCssFromSheet(stylesheet.sheet) : 'body{}'; + const main = document.querySelector('main'); const data = { - main: document.querySelector("main").outerHTML, - // css: `${globalCss} /* GLOBAL-LOCAL */ ${localCss}`, + main: main ? main.outerHTML : '', globalCss, localCss, }; return data; } -function getCssFromSheet(sheet) { - return Array.from(sheet.cssRules) - .map((rule) => rule.cssText) - .join(""); +function getCssFromSheet (sheet) { + return Array.from(sheet.cssRules).map((rule) => rule.cssText).join(''); } // run init if ( - document.readyState === "complete" || - document.readyState === "interactive" + document.readyState === 'complete' || + document.readyState === 'interactive' ) { init(); -} else { - document.addEventListener("DOMContentLoaded", init); +} +else { + document.addEventListener('DOMContentLoaded', init); }