'use strict'; // Cross-browser API namespace. Firefox provides Promise-based `browser.*`; // Chrome MV3 exposes `browser.*` too, but some builds only populate the // `chrome.*` global. Alias to whichever is present. if (typeof browser === 'undefined' || browser == null) { var browser = (typeof chrome !== 'undefined' ? chrome : {}); } function errMsg(err) { return String((err && err.message) || err); } browser.runtime.onMessage.addListener((msg, sender, sendResponse) => { if (msg && msg.type === 'generate-pdf') { generatePdf(msg.data) .then(() => sendResponse({ ok: true })) .catch((err) => sendResponse({ ok: false, error: errMsg(err) })); return true; } }); function formatPeriod(period) { if (!period) return ''; return String(period) .replace(/\b1ST\b/g, '1st') .replace(/\b2ND\b/g, '2nd') .replace(/\b3RD\b/g, '3rd') .replace(/\b(\d+)TH\b/g, '$1th') .toLowerCase() .replace(/^./, (c) => c.toUpperCase()); } async function generatePdf(data) { const bytes = await ISMIStools.buildStudyLoadPdf(data); const blob = new Blob([bytes], { type: 'application/pdf' }); const url = URL.createObjectURL(blob); const header = data.header || {}; const year = parseInt(data.year, 10); const period = formatPeriod(data.period || header.semester || ''); const compactProgram = ISMIStools.compactProgram(header.program || ''); const schoolYear = Number.isFinite(year) ? `${year}-${year + 1}` : ''; const parts = [ header.studentId || (header.fullName ? header.fullName.replace(/\s+/g, ' ') : ''), compactProgram, schoolYear ? 'S.Y. ' + schoolYear : '', period, 'Study Load' ].filter(Boolean); const filename = parts.join(' - ') + '.pdf'; const fallback = 'Study Load - ' + (header.fullName || 'Student') + '.pdf'; const safeFilename = filename || fallback; try { const id = await browser.downloads.download({ url, filename: safeFilename, saveAs: true }); const onChanged = (delta) => { if (delta.id === id && delta.state && (delta.state.current === 'complete' || delta.state.current === 'interrupted')) { browser.downloads.onChanged.removeListener(onChanged); URL.revokeObjectURL(url); } }; browser.downloads.onChanged.addListener(onChanged); } catch (err) { URL.revokeObjectURL(url); throw err; } }