Skip to content

Commit

Permalink
fix(export-element): fallback to export as image when window open is …
Browse files Browse the repository at this point in the history
…not supported (#1269)

* fix: fallback to export as image when window open is not supported

* feat: close png modal on escape key
  • Loading branch information
iamogbz authored Dec 22, 2024
1 parent ed56efe commit afa2442
Showing 1 changed file with 45 additions and 18 deletions.
63 changes: 45 additions & 18 deletions scripts/export-element/index.user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@ import { html2canvas } from "libraries/html2canvas";
target: null,
};

/**
* Create keyboard event handler that triggers callback only on specific key
* TODO: Handle multiple keys and combinations
* TODO: options to prevent default event action and stop propagation
*/
function onKey(params: { key: string; callback: () => void }) {
return (event: KeyboardEvent) => {
if (event.key === params.key) {
params.callback();
}
};
}

/**
* Find the uppermost node that satisfies the predicate
*/
Expand Down Expand Up @@ -75,13 +88,6 @@ import { html2canvas } from "libraries/html2canvas";
return containsAll(nodeText, params.matchWords);
},
);

console.log(
(event.target as Node).textContent,
// @ts-expect-error IE before version 9
document.selection?.createRange?.().text,
params.target,
);
}
document.addEventListener("contextmenu", handleUpdateTarget);
document.addEventListener("mouseup", handleUpdateTarget);
Expand Down Expand Up @@ -171,7 +177,15 @@ import { html2canvas } from "libraries/html2canvas";
"width=800,height=600",
);
if (!newWindow) {
alert("Please allow popups for this site and try again.");
const errorMessage =
"Failed to open new window. Please allow popups for this site and try again.";
const isInIframe = window.self !== window.top;
if (isInIframe) {
console.error(errorMessage);
console.error("Falling back to exporting as image.");
cloneAndDownloadImage(node);
}
alert(errorMessage);
return;
}
const newDocument = newWindow.document;
Expand Down Expand Up @@ -200,14 +214,16 @@ import { html2canvas } from "libraries/html2canvas";
const clone = cloneNodeWithStyles(window, node);
const backgroundColor = findBackgroundColor(node);

const modalContent = document.createElement("div");
const modalContent = document.createElement("a");
modalContent.style.backgroundColor = backgroundColor;
modalContent.style.cursor = "pointer";
modalContent.style.display = "block";
modalContent.style.height = "fit-content";
modalContent.style.padding = "min(1vh, 1vw)";
modalContent.style.position = "relative";
modalContent.style.textDecoration = "none";
modalContent.style.top = "1vh";
modalContent.style.userSelect = "none";
modalContent.style.width = "fit-content";

const modalWrapper = document.createElement("div");
Expand Down Expand Up @@ -264,18 +280,29 @@ import { html2canvas } from "libraries/html2canvas";
.replace(/[/\\?%*:|"<>]+/g, filenameGlue)
.replace(/[-]+/g, filenameGlue)}.${imageType.split("/")[1]}`;

const imageLink = document.createElement("a");
imageLink.target = "_blank";
imageLink.href = dataURI;
imageLink.download = filename;
modalContent.target = "_blank";
modalContent.href = dataURI;
modalContent.download = filename;
modalContent.title = `Download ${filename}`;

modalWrapper.addEventListener("click", () => modalWrapper.remove());
const downloadImage = (e: Event) => {
e.preventDefault();
// prevent modal from closing when clicking on the link
modalContent.addEventListener("click", (e) => {
e.stopPropagation();
return imageLink.click();
// TODO: check if download is permitted by browser
});
const closePreview = () => {
modalWrapper.remove();
URL.revokeObjectURL(dataURI); // free up memory
document.removeEventListener("keydown", closePreviewOnEscape);
};
modalContent.addEventListener("click", downloadImage);
const closePreviewOnEscape = onKey({
key: "Escape",
callback: closePreview,
});
// close modal when clicking outside the link
modalWrapper.addEventListener("click", closePreview);
// close modal when pressing escape
document.addEventListener("keydown", closePreviewOnEscape);
}

/**
Expand Down

0 comments on commit afa2442

Please sign in to comment.