diff --git a/src/components/download.js b/src/components/download.js new file mode 100644 index 0000000..cbfdbc0 --- /dev/null +++ b/src/components/download.js @@ -0,0 +1,54 @@ +const xmlns = "http://www.w3.org/2000/xmlns/"; +const xlinkns = "http://www.w3.org/1999/xlink"; +const svgns = "http://www.w3.org/2000/svg"; + + +export function download(value, name = "untitled", label = "Save") { + console.log("in download"); + const a = document.createElement("a"); + const b = a.appendChild(document.createElement("button")); + b.textContent = label; + a.download = name; + + async function reset() { + await new Promise(requestAnimationFrame); + URL.revokeObjectURL(a.href); + a.removeAttribute("href"); + b.textContent = label; + b.disabled = false; + } + + a.onclick = async event => { + console.log("clicked"); + b.disabled = true; + if (a.href) { + console.log(`already saved: ${a.href}`); + return reset(); // Already saved. + } + b.textContent = "Saving…"; + try { + const object = await (typeof value === "function" ? value() : value); + console.log("svg object:"); + console.log(object); + b.textContent = "Download"; + a.href = URL.createObjectURL(object); // eslint-disable-line require-atomic-updates + console.log(`url = ${a.href}`); + } catch (ignore) { + b.textContent = label; + } + if (event.eventPhase) return reset(); // Already downloaded. + b.disabled = false; + }; + + return a; +} + + +export function serialize_svg(svg) { + svg = svg.cloneNode(true); + svg.setAttributeNS(xmlns, "xmlns", svgns); + svg.setAttributeNS(xmlns, "xmlns:xlink", xlinkns); + const serializer = new window.XMLSerializer; + const string = serializer.serializeToString(svg); + return new Blob([string], {type: "image/svg+xml"}); +}