121 lines
4.0 KiB
JavaScript
121 lines
4.0 KiB
JavaScript
// printExport.js
|
||
// Einbinden: <script src="/scripts/printExport.js"></script>
|
||
// Aufruf: window.printCV(element, cvTitle, cvSettings, template)
|
||
|
||
window.printCV = async function (el, cvTitle, cvSettings, template) {
|
||
|
||
// ── 1. Lokale CSS-Datei direkt fetchen (kein CORS-Problem) ──────
|
||
let globalCss = '';
|
||
try {
|
||
globalCss = await fetch('/styles/global.css').then(r => r.text());
|
||
} catch (e) {
|
||
console.warn('global.css nicht geladen', e);
|
||
}
|
||
|
||
// ── 2. Inline <style> Tags sammeln (Astro Scoped CSS) ───────────
|
||
const inlineStyles = Array.from(document.querySelectorAll('style'))
|
||
.map(s => s.textContent).join('\n');
|
||
|
||
// ── 3. Google Fonts URL ─────────────────────────────────────────
|
||
const fontUrl = 'https://fonts.googleapis.com/css2?family=Inter:wght@400;600&family=Lora:ital,wght@0,400;0,600;1,400&family=Merriweather:wght@400;700&family=Montserrat:wght@300;400;600;700&family=Outfit:wght@300;400;600&family=Oswald:wght@400;600&family=Playfair+Display:ital,wght@0,400;0,700;1,400&family=Roboto:wght@300;400;700&display=swap';
|
||
|
||
// ── 4. Sidebar-Body-Gradient (wiederholt sich auf jeder Seite) ──
|
||
const SIDEBAR_WIDTH = { 1: '220px', 2: '0', 3: '160px', 4: '240px' };
|
||
const sw = SIDEBAR_WIDTH[template] || '0';
|
||
const color = (cvSettings && cvSettings.primaryColor) || '#1B2A5E';
|
||
|
||
const sidebarCss = sw !== '0' ? `
|
||
body {
|
||
background: linear-gradient(to right, ${color} ${sw}, white ${sw}) !important;
|
||
-webkit-print-color-adjust: exact !important;
|
||
print-color-adjust: exact !important;
|
||
}
|
||
/* Sidebar transparent – Farbe kommt von body-Hintergrund */
|
||
.t1-sidebar { background: transparent !important; }
|
||
.t3-left { background: transparent !important; }
|
||
.t4-left { background: transparent !important; }
|
||
` : '';
|
||
|
||
// ── 5. Komplettes HTML zusammenbauen ────────────────────────────
|
||
const html = `<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>${cvTitle || 'Lebenslauf'}</title>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link href="${fontUrl}" rel="stylesheet">
|
||
<style>
|
||
/* ── global.css ── */
|
||
${globalCss}
|
||
|
||
/* ── Astro Scoped Styles ── */
|
||
${inlineStyles}
|
||
|
||
/* ── Print Overrides (am Ende = höchste Priorität) ── */
|
||
@page {
|
||
size: A4 portrait;
|
||
margin: 0;
|
||
}
|
||
|
||
html {
|
||
margin: 0;
|
||
padding: 0;
|
||
}
|
||
|
||
body {
|
||
margin: 0 !important;
|
||
padding: 0 !important;
|
||
display: flex;
|
||
justify-content: center;
|
||
background: white;
|
||
}
|
||
|
||
${sidebarCss}
|
||
|
||
.cv-a4 {
|
||
width: 210mm !important;
|
||
min-height: 297mm !important;
|
||
box-shadow: none !important;
|
||
margin: 0 !important;
|
||
}
|
||
|
||
* {
|
||
-webkit-print-color-adjust: exact !important;
|
||
print-color-adjust: exact !important;
|
||
}
|
||
|
||
.t1-entry, .t1-sec,
|
||
.t2-tl-item, .t2-sec,
|
||
.t3-entry, .t3-sec,
|
||
.t4-entry, .t4-sec {
|
||
break-inside: avoid;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>${el.innerHTML}</body>
|
||
</html>`;
|
||
|
||
// ── 6. Blob-URL statt document.write ────────────────────────────
|
||
const blob = new Blob([html], { type: 'text/html; charset=utf-8' });
|
||
const blobUrl = URL.createObjectURL(blob);
|
||
|
||
const win = window.open(blobUrl, '_blank', 'width=900,height=1200');
|
||
if (!win) {
|
||
alert('Popup wurde blockiert. Bitte Popup-Blocker deaktivieren.');
|
||
URL.revokeObjectURL(blobUrl);
|
||
return;
|
||
}
|
||
|
||
win.addEventListener('load', () => {
|
||
// Blob-URL freigeben sobald geladen
|
||
URL.revokeObjectURL(blobUrl);
|
||
|
||
// Fonts + base64-PNGs (Icons) etwas Zeit geben
|
||
setTimeout(() => {
|
||
win.focus();
|
||
win.print();
|
||
win.addEventListener('afterprint', () => win.close());
|
||
}, 1000);
|
||
});
|
||
}; |