-
Notifications
You must be signed in to change notification settings - Fork 0
/
cap.js
88 lines (81 loc) · 3.15 KB
/
cap.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
function main() {
const gradeMap = new Map([
['A+', 5],
['A', 5],
['A-', 4.5],
['B+', 4],
['B', 3.5],
['C+', 3],
['C', 2.5],
['D+', 2],
['D', 1.5],
['F', 0],
]);
// constants, extracted for maintainability
const GRADED_MC_ELEMENT_ID = 'DERIVED_SSS_GRD_SSS_UNIT_DISP_4$0';
const UNGRADED_MC_ELEMENT_ID = 'DERIVED_SSS_GRD_SSS_UNIT_DISP_4$1';
const CAP_ELEMENT_ID = 'DERIVED_SSS_GRD_SSS_UNIT_DISP_4$2';
const GRADE_ELEMENT_ID_PREFIX = 'N_STDNT_ENRL_V2_CRSE_GRADE_OFF';
const ROW_ELEMENT_ID_PREFIX = 'TERM_CLASSES';
const UNIT_ID_PREFIX = 'N_STDNT_ENRL_V2_UNT_TAKEN';
// HTML elements holding the values
const gradedMCElement = document.getElementById(GRADED_MC_ELEMENT_ID);
const ungradedMCElement = document.getElementById(UNGRADED_MC_ELEMENT_ID);
const CAPElement = document.getElementById(CAP_ELEMENT_ID);
// global variables
const initialCAP = parseFloat(CAPElement.innerText);
const initialGradedMC = parseFloat(gradedMCElement.innerText);
const allMC = initialGradedMC + parseFloat(ungradedMCElement.innerText);
let currentEarned = initialCAP * initialGradedMC;
let currentGradedMC = initialGradedMC;
// invoked when row is clicked
function clickSU(rowElement) {
const multiplier = rowElement.changed ? 1 : -1;
const gradeElement = rowElement.querySelector(`[id^="${GRADE_ELEMENT_ID_PREFIX}"]`);
currentEarned += rowElement.earned * multiplier;
currentGradedMC += rowElement.unit * multiplier;
// below is changing displayed text
const newUngradedMC = allMC - currentGradedMC;
let newCAP = currentEarned / currentGradedMC;
if (Number.isNaN(newCAP)) {
newCAP = 0;
}
const suText = rowElement.earned >= 2.0 ? 'S' : 'U';
const newGrade = rowElement.changed ? rowElement.grade : suText;
gradedMCElement.innerText = currentGradedMC.toFixed(2);
ungradedMCElement.innerText = newUngradedMC.toFixed(2);
CAPElement.innerText = `${newCAP.toFixed(2)} (${(newCAP - initialCAP).toFixed(2)})`;
gradeElement.innerText = newGrade;
if (!rowElement.changed) {
gradeElement.style.fontWeight = 'bold';
gradeElement.style.color = 'red';
} else {
gradeElement.style.fontWeight = 'normal';
gradeElement.style.color = 'initial';
}
rowElement.changed = !rowElement.changed;
}
// add various necessary attributes to rows
function attachAttributes() {
document.querySelectorAll(`[id^="${ROW_ELEMENT_ID_PREFIX}"]`).forEach((rowElement) => {
const gradeText = rowElement.querySelector(`[id^="${GRADE_ELEMENT_ID_PREFIX}"]`).innerText;
if (gradeMap.has(gradeText)) {
rowElement.grade = gradeText;
rowElement.unit = parseFloat(rowElement.querySelector(`[id^="${UNIT_ID_PREFIX}"]`).innerText);
rowElement.earned = rowElement.unit * gradeMap.get(gradeText);
rowElement.changed = false;
rowElement.onclick = function clicked() { clickSU(this); };
rowElement.style.cursor = 'pointer';
}
});
}
attachAttributes();
}
const observer = new MutationObserver(main);
observer.observe(document, {
subtree: true,
childList: true,
attributes: true,
characterData: true,
});
main();