(function () { 'use strict'; const MASTER_KEY = 'enabled'; async function isEnabled() { const { enabled } = await browser.storage.local.get(MASTER_KEY); return enabled !== false; } function autoAcceptPrivacy() { const modal = document.getElementById('myModal'); if (!modal) return; const checkbox = document.getElementById('Confirmation'); const submit = document.getElementById('Submit'); if (checkbox && !checkbox.checked) checkbox.click(); if (submit) submit.click(); } function watchPrivacyModal() { autoAcceptPrivacy(); const observer = new MutationObserver(() => autoAcceptPrivacy()); observer.observe(document.body, { childList: true, subtree: true }); setTimeout(() => observer.disconnect(), 30000); } async function autoLogin() { const { profiles } = await browser.storage.local.get('profiles'); const active = (profiles || []).find((p) => p.enabled); if (!active) return; const userField = document.querySelector( 'input[name="UserName"], input[name="username"], input[id="UserName"], input[id="username"]' ); const passField = document.querySelector('input[type="password"]'); if (!userField || !passField) return; userField.value = active.username; passField.value = active.password; userField.dispatchEvent(new Event('input', { bubbles: true })); passField.dispatchEvent(new Event('input', { bubbles: true })); const form = userField.closest('form') || passField.closest('form'); if (!form) return; setTimeout(() => { const submitBtn = form.querySelector('input[type="submit"], button[type="submit"]'); if (submitBtn) submitBtn.click(); else form.submit(); }, 300); } async function fetchCourseDescription(courseCode, academicPeriod, academicYear, token) { const body = new URLSearchParams(); body.set('Courses', courseCode); body.set('AcademicPeriod', academicPeriod); body.set('AcademicYear', academicYear); body.set('AjaxFormVM.Controller', 'CourseSchedule'); body.set('AjaxFormVM.Action', 'CourseScheduleOffered'); body.set('AjaxFormVM.ResultTargetId', 'CourseScheduleOfferedList'); body.set('AjaxFormVM.LinkToReturn', ''); body.set('AjaxFormVM.LinkToReturnTargetId', ''); body.set('AjaxFormVM.FormHeader', 'Choose term to view courses offered'); body.set('AjaxFormVM.FormHeaderIcon', ''); body.set('AjaxFormVM.FormId', 'CourseScheduleCourseScheduleOffered'); body.set('AjaxFormVM.ShowCloseButton', 'True'); body.set('AjaxFormVM.PreventAutoUpdateTarget', 'True'); body.set('AjaxFormVM.CloseModalAfterSubmit', 'False'); body.set('AjaxFormVM.AjaxFormType', 'Search'); body.set('AjaxFormVM.FormNoteLocation', ''); body.set('AjaxFormVM.SubmitButton.FaIcon', ''); body.set('AjaxFormVM.SubmitButton.ButtonText', ''); body.set('AjaxFormVM.SubmitButton.ButtonSize', ''); body.set('__RequestVerificationToken', token); const resp = await fetch('/CourseSchedule/CourseScheduleOffered?Length=14', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 'X-Requested-With': 'XMLHttpRequest' }, body: body.toString(), credentials: 'same-origin' }); if (!resp.ok) throw new Error('Offered courses request failed: ' + resp.status); const html = await resp.text(); const courses = ISMIStools.parseOfferedCourses(html); const match = courses.find((c) => c.courseCode === courseCode); return match ? match.description : ''; } function extractTotalUnits(text) { const m = /Total Units:\s*([\d.]+)/i.exec(text); return m ? m[1] : ''; } async function scrapeStudyLoad() { const table = document.querySelector('table.table-forum'); if (!table) throw new Error('No study load table found on this page.'); const courses = ISMIStools.parseStudyLoadTable(table.outerHTML); if (!courses.length) throw new Error('No courses found in study load table.'); const periodEl = document.getElementById('AcademicPeriod'); const yearEl = document.getElementById('AcademicYear'); const tokenEl = document.querySelector('input[name="__RequestVerificationToken"]'); const academicPeriod = periodEl ? periodEl.value : ''; const academicYear = yearEl ? yearEl.value : ''; const token = tokenEl ? tokenEl.value : ''; const uniqueCodes = [...new Set(courses.map((c) => c.courseCode))]; const descMap = {}; for (const code of uniqueCodes) { try { descMap[code] = await fetchCourseDescription(code, academicPeriod, academicYear, token); } catch (e) { descMap[code] = ''; } } courses.forEach((c) => { c.description = descMap[c.courseCode] || ''; }); let header = {}; try { const resp = await fetch('/Manage/Student', { credentials: 'same-origin' }); if (!resp.ok) throw new Error('Profile request failed: ' + resp.status); const html = await resp.text(); header = ISMIStools.parseProfilePage(html); } catch (e) { header = {}; } const totalUnits = extractTotalUnits(document.body.innerText); return { header, courses, totalUnits }; } browser.runtime.onMessage.addListener((msg, sender, sendResponse) => { if (msg && msg.type === 'scrape-study-load') { scrapeStudyLoad() .then((data) => sendResponse({ ok: true, data })) .catch((err) => sendResponse({ ok: false, error: String((err && err.message) || err) })); return true; // async response } }); (async function init() { if (!(await isEnabled())) return; watchPrivacyModal(); if (/\/Account\/Login/i.test(location.href)) autoLogin(); })(); })();