2 Commits

Author SHA1 Message Date
hikari 23df8a3423 feat: replace formats text with download and print buttons
Node.js CI / CI (push) Failing after 23s
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 52s
Adds four action buttons: download YAML, download JSON, print full
resume, and print condensed resume. The condensed print temporarily
hides certifications, projects, and publications sections before
opening the print dialog, restoring them on afterprint.
2026-04-20 12:32:42 -07:00
hikari 7b8cda989b fix: restore print media query functionality
Removes CDN global styles before printing via beforeprint/afterprint
events, preventing the witchy theme from bleeding into print output.
Fixes print layout: centred name and contact info, reset margins for
compact sub-position lists, and footer z-index for screen view.
2026-04-20 12:10:18 -07:00
2 changed files with 54 additions and 3 deletions
+42 -3
View File
@@ -28,6 +28,42 @@ const htmlBeginning = `<!DOCTYPE html>
const htmlEnd = ` </main>
</body>
<script src="./dates.js"></script>
<script>
var _cdnStyle = null;
var _condensedSections = [];
window.addEventListener("beforeprint", function() {
_cdnStyle = document.getElementById("nhcarrigan-global-styles");
if (_cdnStyle) { _cdnStyle.remove(); }
});
window.addEventListener("afterprint", function() {
if (_cdnStyle) { document.head.appendChild(_cdnStyle); _cdnStyle = null; }
_condensedSections.forEach(function(el) { el.style.display = ""; });
_condensedSections = [];
});
function downloadFile(url, filename) {
fetch(url)
.then(function(r) { return r.blob(); })
.then(function(blob) {
var a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(a.href);
});
}
function printCondensed() {
["certifications", "projects", "publications"].forEach(function(id) {
var el = document.getElementById(id);
if (el) { el.style.display = "none"; _condensedSections.push(el); }
});
window.print();
}
</script>
</html>`;
const request = await fetch(
@@ -114,9 +150,12 @@ const heading = `<h1>${yaml.name}</h1>
<a href="#projects">Projects</a> |
<a href="#publications">Publications</a> |
</p>
<p id="formats">
Get this resume in <a href="https://data.nhcarrigan.com/resume.yml">YAML</a> or <a href="https://data.nhcarrigan.com/resume.json">JSON</a> format. You can also <span style="text-decoration: underline" onclick="window.print();return false;">print</span> the resume (and optionally save as a PDF).
</p>
<div id="formats">
<button onclick="downloadFile('https://data.nhcarrigan.com/resume.yml', 'resume.yml')">Download YAML</button>
<button onclick="downloadFile('https://data.nhcarrigan.com/resume.json', 'resume.json')">Download JSON</button>
<button onclick="window.print()">Print Resume</button>
<button onclick="printCondensed()">Print Condensed Resume</button>
</div>
<p class="cta">
Interested in hiring me?
<a href="https://testimonials.nhcarrigan.com" target="_blank"
+12
View File
@@ -42,6 +42,9 @@ hr {
box-shadow: 4px 4px 4px rgba(0, 0, 0, 0.7);
margin-bottom: 10px;
}
footer {
z-index: 1;
}
}
@media print {
:root {
@@ -50,6 +53,15 @@ hr {
* {
color: black;
font-family: "Times New Roman", serif;
margin: 0;
padding: 0;
}
h1 {
text-align: center;
font-size: 1.8rem;
}
.info {
text-align: center;
}
video,
footer,