# ISMIS Helper — Firefox Extension Design **Date:** 2026-08-18 **Status:** Approved **Target site:** `https://ismis.usc.edu.ph` (USC ISMIS student portal) ## Overview A personal Firefox extension (Manifest V3, no build step) that improves the USC ISMIS 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. **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. ## Architecture Single MV3 extension, plain JavaScript, no bundler. No background script — all logic runs in the content script (scraping and print-document building happen in-page). ``` ismis-helper/ ├── 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 ├── 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. - 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 - Content script runs on `https://ismis.usc.edu.ph/Account/Login`. - Reads the active (enabled) profile from `browser.storage.local`. - Locates the username and password input fields (`name`/`id` = `Username` / `Password`, with fallback variants). - Fills both fields, then submits the form (auto-submit). - If no profile is enabled, or the master toggle is off, does nothing. ## Component 2 — Auto-accept Privacy Policy - On any portal page, if the privacy modal `#myModal` is present and visible: - Check the `#Confirmation` checkbox ("I have read and understood the Privacy Policy Statement"). - Click the `#Submit` button (Continue), which is disabled until the checkbox is checked. - Gated by the master toggle. ## Component 3 — Profiles - Stored in `browser.storage.local` under key `profiles` as an array of: `{ id, name, username, password, enabled }`. - Popup provides add, edit, delete, and enable/disable per profile. - Only one profile can be enabled at a time (enabling one disables the others); that profile is used for auto-login. - Master toggle stored under key `enabled` (boolean). ## 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 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, Status) via `parseStudyLoadTable`. - **Header info** (full name, student ID, program, year level, semester) is scraped from the **My Profile** page (`/Manage/Student`). ### Filtering - **DISSOLVED courses are excluded** (`filterStudyLoadCourses`). - Total units = sum of the included courses' units (`sumUnits`). ### Description lookup - For each unique course code, POST to `https://ismis.usc.edu.ph/CourseSchedule/CourseScheduleOffered` with the `__RequestVerificationToken` and selected `AcademicPeriod`/`AcademicYear`, then parse the returned table for the **Course Description**. - If lookup fails for a course, the description is left blank and generation continues. ### 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 DISSOLVED + description lookup) │ ▼ browser.runtime.sendMessage({ type: 'generate-pdf', data }) background.js (pdf-lib buildStudyLoadPdf) │ ▼ 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, 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 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 inline with the total-units footer, excludes DISSOLVED courses, and downloads a Letter-size PDF.