Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chrome was saying sheet was null, and throwing type error #36

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
209 changes: 106 additions & 103 deletions src/content_script.js
Original file line number Diff line number Diff line change
@@ -1,58 +1,60 @@
const buttonOuterHTMLFallback = `<button class="btn flex justify-center gap-2 btn-neutral" id="download-png-button">Try Again</button>`;
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;
}
Expand All @@ -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();
}
Expand All @@ -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;
Expand All @@ -119,45 +121,46 @@ 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;
// a.download = "chat-gpt-image.png";
// 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) {
Expand All @@ -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);
}