From cdcc5cadcdaba10db6dffab705f339cd4528f92b Mon Sep 17 00:00:00 2001
From: Jon Manning
Date: Mon, 25 Mar 2024 16:26:31 +1100
Subject: [PATCH] Add PDF export feature
---
src/index.html | 4 ++++
src/index.ts | 10 +++++++++-
src/playground.ts | 43 +++++++++++++++++++++++++++++++++++++++++--
3 files changed, 54 insertions(+), 3 deletions(-)
diff --git a/src/index.html b/src/index.html
index 7497867..84fdc59 100644
--- a/src/index.html
+++ b/src/index.html
@@ -31,6 +31,10 @@ Try Yarn Spinner
id="yarn-spinner-version-value">
+
diff --git a/src/index.ts b/src/index.ts
index 5430d8d..13e3b7d 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,5 +1,11 @@
import { initialContent } from './starter-content'
+// Hide the PDF button if 'pdf' is not part of the query
+let params = new URLSearchParams(window.location.search);
+if (params.has("pdf")) {
+ document.getElementById("button-download-pdf").classList.remove("d-none");
+}
+
window.addEventListener('load', async function () {
// First, determine what content we want to load. If the url contains a
@@ -15,12 +21,14 @@ window.addEventListener('load', async function () {
contentName = hashComponents[0]
}
+
+
// Wait for the playground module to finish being downloaded, and then
// import it. Once that's done, load the playground with the content that we
// selected.
const playground = await import("./playground");
await playground.load(contentName);
-
+
// Hide the loading element, which is visible before any script runs.
global.document.getElementById("loader").classList.add("d-none");
diff --git a/src/playground.ts b/src/playground.ts
index c4c79de..deca79a 100644
--- a/src/playground.ts
+++ b/src/playground.ts
@@ -350,7 +350,46 @@ export async function load (initialContentName : string = "default") {
const fileName = "Runner.html";
downloadFile(html, fileName);
- })
+ });
+
+ let pdfDownloadInProgress = false;
+
+ document.getElementById("button-download-pdf").addEventListener("click", async => {
+ if (pdfDownloadInProgress) {
+ return;
+ }
+
+ pdfDownloadInProgress = true;
+ const pdfServer = 'https://books-generator.yarnspinner.dev';
+ const pdfEndpoint = pdfServer + '/get-pdf';
+
+ var source = editor.getModel().getValue();
+
+ const icon = document.getElementById("button-download-pdf-icon");
+ const spinner = document.getElementById("button-download-pdf-spinner");
+
+ icon.classList.add("d-none");
+ spinner.classList.remove("d-none");
+
+ fetch(pdfEndpoint, {
+ method: 'POST',
+ body: source,
+ }).then(async (response) => {
+ if (response.status !== 200) {
+
+ console.error(await response.text());
+ alert("Sorry, there was a problem downloading your PDF.");
+ return;
+ }
+ var blob = await response.blob();
+ downloadFile(blob, "YarnSpinner-Book.pdf");
+ }).finally(() => {
+ icon.classList.remove("d-none");
+ spinner.classList.add("d-none");
+
+ pdfDownloadInProgress = false
+ });
+ });
// Finally, compile our source immediately.
compileSource();
@@ -402,7 +441,7 @@ async function compileSource() {
}
}
-function downloadFile(source: string, fileName: string) {
+function downloadFile(source: string | Blob, fileName: string) {
if (window.navigator && (window.navigator as any).msSaveOrOpenBlob) {
// IE11 support
let blob = new Blob([source], { type: "application/octet-stream" });