feat: restore direct PDF download via background; drop printdoc

This commit is contained in:
adrianbonpin
2026-08-18 19:38:26 +08:00
parent 8bcfee341c
commit 1537881ebc
9 changed files with 304 additions and 197 deletions
@@ -11,10 +11,10 @@ student portal experience. It provides three features:
1. **Auto-login** — auto-fill and auto-submit the login form from a saved profile.
2. **Auto-accept Privacy Policy** — dismiss the recurring privacy-policy modal.
3. **Printable Study Load** — an on-page "Download PDF" button on the Study Load page
that opens a print-ready Letter-size document replicating the official ISMIS Study
Load (with course descriptions looked up from the Offered Courses endpoint),
triggering the browser print dialog so the user can print or "Save as PDF".
3. **Study Load PDF** — an on-page "Download PDF" button on the Study Load page that
generates a PDF replicating the official ISMIS Study Load document (Letter size,
with course descriptions looked up from the Offered Courses endpoint) and
downloads it directly.
A single **master toggle** disables all extension behavior on the portal.
@@ -25,21 +25,29 @@ runs in the content script (scraping and print-document building happen in-page)
```
ismis-helper/
├── manifest.json # MV3 manifest, permissions, content script, popup
├── content.js # runs on ismis.usc.edu.ph: auto-login, privacy, button, print flow
├── manifest.json # MV3 manifest, permissions, content script, popup, background
├── background.js # message handler: build PDF (pdf-lib) + download via downloads API
├── content.js # runs on ismis.usc.edu.ph: auto-login, privacy, button, scrape
├── parsers.js # UMD: table/profile/offered-courses parsing + filtering
├── printdoc.js # UMD: buildStudyLoadHtml (Letter-size printable document)
├── pdf.js # UMD: buildStudyLoadPdf (Letter PDF, official layout, pagination)
├── popup.html # popup UI (master toggle + profiles)
├── popup.js # popup logic
├── popup.css # popup styles
├── libs/pdf-lib.min.js # vendored pdf-lib library (used by background)
└── icons/ # extension icons (16, 32, 48, 128)
```
### Permissions (manifest.json)
- `storage` — persist profiles and the master toggle.
- `downloads` — save the generated Study Load PDF.
- `host_permissions` — `https://ismis.usc.edu.ph/*` for the content script.
- No background, no `downloads` permission (the print flow uses `window.open` +
the browser's print dialog).
- Background loads `libs/pdf-lib.min.js` + `pdf.js` via `background.scripts`.
## Background script
- `background.js` handles the `generate-pdf` message from the content script:
builds the PDF via `ISMIStools.buildStudyLoadPdf`, wraps the bytes in a Blob,
downloads via `browser.downloads.download({ saveAs: true })`, and revokes the
object URL when the download reaches `complete`/`interrupted` (and on failure).
## Component 1 — Auto-login
@@ -68,13 +76,14 @@ ismis-helper/
that profile is used for auto-login.
- Master toggle stored under key `enabled` (boolean).
## Component 4 — Printable Study Load
## Component 4 — Study Load PDF
### On-page button
- The content script watches the Study Load page (`#StudyLoad`). When the course
table appears (after the user selects academic period/year and searches), it
injects a **"Download PDF"** button below the `12.00 Units / Total Units: 18.00`
footer, styled like the page's buttons (`btn green pull-right`).
injects a **"Download PDF"** button inline with the
`12.00 Units / Total Units: 18.00` footer (button on the left, units text on the
right, via a flex row), styled like the page's buttons (`btn green`).
### Scrape
- Parse the course table (columns: Group #, Course Code, Schedule, Faculty, Units,
@@ -94,44 +103,43 @@ ismis-helper/
- If lookup fails for a course, the description is left blank and generation
continues.
### Print document
- `buildStudyLoadHtml` (printdoc.js) produces a self-contained HTML document at the
official dimensions (**Letter, 8.5in × 11in** via `@page`), replicating the official
layout: title block (STUDENT'S STUDY LOAD, semester, date range, date enrolled),
student info row (ID, name, program, year level), the course table (GROUP, COURSE,
COURSE DESCRIPTION, TEACHER, UNITS, NOTE — NOTE is the status), and a footer
(total units, "Printed by: …").
- The button opens this document in a new window and auto-triggers
`window.print()`, so the user prints or "Save as PDF" at the official dimensions.
- All scraped/entered values are HTML-escaped.
### PDF generation
- `pdf.js` (`buildStudyLoadPdf`, using **pdf-lib**) builds a Letter-size (612×792pt)
PDF replicating the official layout: title block (STUDENT'S STUDY LOAD, semester,
date range, date enrolled), student info row (ID, name, program, year level), the
course table (GROUP, COURSE, COURSE DESCRIPTION, TEACHER, UNITS, NOTE — NOTE is
the status), and a footer (total units, "Printed by: …"). Multi-page
pagination re-draws the table header. NOTE column is wide enough for `REGULAR`.
- The content script sends the data to the background (`generate-pdf`), which
downloads the PDF via the `downloads` API (`saveAs: true`).
## Data flow
```
Study Load page ──▶ content script (scrape + filter + description lookup)
Study Load page ──▶ content script (scrape + filter DISSOLVED + description lookup)
│
▼ browser.runtime.sendMessage({ type: 'generate-pdf', data })
background.js (pdf-lib buildStudyLoadPdf)
│
▼
buildStudyLoadHtml (printdoc.js)
│
▼
window.open + window.print() → print / Save as PDF (Letter)
browser.downloads.download → Study Load PDF file
```
## Error handling
- Master toggle off → no extension behavior on the portal.
- No enabled profile → no auto-login.
- Description lookup fails for a course → blank description, document still opens.
- No enrolled (non-DISSOLVED) courses → error toast, no window opened.
- Popup blocked → toast explaining popups must be allowed for the site.
- Description lookup fails for a course → blank description, PDF still generated.
- No enrolled (non-DISSOLVED) courses → error toast, no download.
- Download fails → error toast; object URL is revoked.
## Testing
- Node `node:test` suites: parsers (table/profile/offered-courses/filter/sum) and
printdoc (page size, layout, escaping, auto-print).
pdf (valid Letter PDF output).
- Load via `about:debugging` → "Load Temporary Add-on".
- Verify auto-login on the login page.
- Verify privacy modal auto-accept.
- Verify profile add/edit/delete/toggle and master toggle.
- Verify the on-page Download PDF button: appears below the total-units footer,
excludes DISSOLVED courses, and opens the Letter-size printable document.
- Verify the on-page Download PDF button: appears inline with the total-units
footer, excludes DISSOLVED courses, and downloads a Letter-size PDF.