IC Insight is a Chrome Manifest V3 extension. All logic runs client-side. The only external network calls made are to the logged-in user's own Infinite Campus instance via the IC REST API (see Network Refresh).
File Structure
extension/
├── manifest.json # Extension config: permissions, content scripts, pages
├── background.js # Service worker: handles ICI_IC_FETCH messages for IC API calls
├── ic-api-client.js # ICApiClient: IC REST API session check and grade fetch logic
├── content.js # Content script: overlay rendering, DOM parsing, caching
├── sebi-prefs.js # Content script: SEBI preference helpers, SEBI.normalizeCategoryKey()
├── styles.css # Overlay base styles and CSS variable fallbacks
├── themes.css # Full light/dark theme CSS variable definitions
├── dashboard.html/.js/.css # Hub page: course cards, GPA, sorting, sparklines
├── details.html/.js # Per-course deep-dive page: breakdown, permanent edits, history chart
├── options.html/.js # Settings page
├── popup.html/.js # Extension toolbar popup
├── gpa-engine.js # GPAEngine: quality-points GPA calculation (cumulative)
├── storage-manager.js # StorageManager: schema versioning, past report cards, import/export
├── scenarios-manager.js # ScenariosManager: CRUD for named what-if scenarios
├── drag-drop-handler.js # DragDropHandler: Dashboard card ordering (drag + sort modes)
├── refresh-controller.js # RefreshController: bulk course refresh with network/classic strategies
├── history-snapshots.js # HistorySnapshots: snapshot CRUD and deduplication
├── trends-engine.js # TrendsEngine: time-series data shaping for the history chart
├── charts.js # Chart rendering (sparklines + full history chart)
├── user-prefs.js # UserPrefs: theme, color palette, welcome messages, user name
├── onboarding-tour.js # OnboardingTour: first-use guided tour
└── icons/ # Extension icon images
Entry Points
| Entry Point |
How triggered |
Purpose |
content.js + sebi-prefs.js |
Injected on every *.infinitecampus.org page at document_idle |
Overlay panel, parsing, caching |
background.js |
Loaded as service worker |
Handles ICI_IC_FETCH messages - makes credentialed fetch() calls to the IC API on behalf of extension pages |
popup.html |
User clicks extension icon |
Links to Dashboard, Options, overlay re-center |
dashboard.html |
Opened manually or via overlay Dashboard button |
Full course hub |
details.html?key=… |
Opened via Dashboard "View details" link |
Per-course breakdown + history |
options.html |
Via popup or Chrome extensions menu |
All settings |
Data Flow
Parse → Cache → Display
User visits IC grades page
│
▼
content.js: initializeICI()
│ detects grades page / iframe
▼
parseModel() ──► parseModelWithQuarters() ──► parseCategoriesInSection()
│ │ │
│ parseQuarterInfo() extractScore/Multiplier/DroppedFlag
│
▼
computeBreakdown(model, sebiPrefs)
│ applies: permEdits → permAdds → whatIfAdds → whatIfDrops/Edits
│ resolves: letter grades → numeric
│ adds: synthetic rolled-up past-quarter assignments (rolling mode)
│
▼
setSummary() + renderBreakdown() → overlay panel rendered
│
▼
cacheSnapshot(model)
│ computes breakdown WITHOUT perm edits/adds
│ merges new quarters with existing cached quarters
│ writes to chrome.storage.local[courseKey]
│ updates ICI_CACHE_INDEX
│ captureHistorySnapshot() (manual source only)
Dashboard Load
dashboard.html opens
│
▼
loadIndexCore()
├── loads ICI_CACHE_INDEX, ICI_GPA_SCALE, ICI_GPA_WEIGHTS
├── deduplicates courses by name (merge)
├── applies DragDropHandler.applySorting()
│
├── for each course key:
│ ├── load snapshot from storage
│ ├── applyPermOverrides(cats, PE_key, PA_key)
│ ├── recomputeOverall(cats, sebiPrefs, key, quarters, gradebookLogic)
│ └── render course card + sparkline
│
├── compute currentYearGPA
├── autoCaptureAllCourses() → HistorySnapshots.captureSnapshot() for each
├── updateCumulativeGPA() → GPAEngine.calculateCumulativeGPA()
└── loadPastReportCards()
Module Globals
content.js module-level state
| Variable |
Type |
Purpose |
currentModel |
object | null |
Currently parsed course model from the page |
whatIfAdds |
array |
Active what-if addition items |
whatIfDrops |
array |
Active what-if drop items |
whatIfEdits |
array |
Active what-if edit items |
permEdits |
object |
Active permanent score overrides keyed by `quarterId |
permAdds |
array |
Active permanent assignment additions |
uiState |
object |
Overlay position, size, minimized state |
sebiPrefs |
object |
SEBI preferences for current course (categoryKey → boolean) |
Global window objects (loaded as scripts)
window.SEBI - from sebi-prefs.js
window.GPAEngine - from gpa-engine.js
window.StorageManager - from storage-manager.js
window.ScenariosManager - from scenarios-manager.js
window.DragDropHandler - from drag-drop-handler.js
window.HistorySnapshots - from history-snapshots.js
window.TrendsEngine - from trends-engine.js
window.UserPrefs - from user-prefs.js
window.ICApiClient - from ic-api-client.js (loaded in dashboard.html before refresh-controller.js)
Permissions
| Permission |
Reason |
storage |
All data is stored locally in chrome.storage.local |
activeTab |
Popup can send messages to the currently active IC tab |
tabs |
chrome.tabs.query used to locate an open IC tab during session validation |
Host: *.infinitecampus.org/*, infinitecampus.org/* |
Content script injection scope; also required for background SW to make credentialed API calls |