(function () {
"use strict";
const FACS = new Set();
const DEPTS = new Map();
// maintain: CDM Advanced Search,
// console.log(Array.prototype.map.call(document.getElementsByName("subjectPopup")[0].children,(e)=>'"'+e.textContent.match(/[A-Z]{2,4}/)[0] + '"').join(", "))
[
["AP", "ADMB", "ADMS", "ANTH", "ARB", "ASL", "CCY", "CDNS", "CH", "CLST", "CLTR", "COGS", "COMN", "CRIM", "DEMS", "DLLL", "ECON", "EN", "ESL", "FND", "FR", "GCIN", "GEOG", "GER", "GK", "GKM", "GWST", "HEB", "HIST", "HREQ", "HRM", "HUMA", "INDG", "INDV", "IT", "ITEC", "JC", "JP", "KOR", "LA", "LASO", "LING", "LLS", "MIST", "MODR", "PERS", "PHIL", "POLS", "POR", "PPAS", "PRWR", "RU", "SOCI", "SOSC", "SOWK", "SP", "SWAH", "SXST", "TESL", "TYP", "WKLS", "WRIT"],
["ED", "AUCO", "BBED", "BIOL", "CHEM", "DANC", "DEST", "DRAA", "ECON", "EDFE", "EDFR", "EDIN", "EDIS", "EDJI", "EDPJ", "EDPR", "EDST", "EDUC", "EN", "ENVS", "FAST", "FREN", "GEOG", "HEB", "HIST", "INDS", "LAW", "LLDV", "MATH", "MUSI", "ORCO", "PHED", "PHIL", "PHYS", "POLS", "PRAC", "SCIE", "SLGS", "SOSC", "TECH", "TLSE", "VISA"],
["ES", "ENVS"],
["FA", "ARTH", "DANC", "DATT", "DESN", "FACS", "FILM", "INDV", "MUSI", "PANF", "THEA", "VISA", "YSDN"],
["GL", "BIOL", "BUEC", "CAT", "CDNS", "COMS", "CSLA", "DRST", "ECON", "EN", "ENSL", "FRAN", "FSL", "GWST", "HIST", "HUMA", "ILST", "ITEC", "LIN", "LYON", "MATH", "MODR", "NATS", "PHIL", "PHYS", "POLS", "PSYC", "SOCI", "SOSC", "SP", "SXST", "TRAN", "WKST", "WMST"],
["GS", "ANTH", "ARTH", "BIOL", "BLIS", "CDIS", "CGTA", "CHEM", "CIVL", "CMCT", "DANC", "DEMS", "DIGM", "DVST", "ECON", "EDUC", "EECS", "EIL", "EN", "ENG", "ENVS", "ESS", "FACC", "FILM", "FREN", "GEOG", "GFWS", "HIST", "HLTH", "HRM", "HUMA", "INST", "INTE", "ITEC", "KAHS", "LAL", "LAW", "LREL", "MATH", "MDES", "MECH", "MUSI", "NURS", "OVGS", "PACC", "PHIL", "PHYS", "PIA", "POLS", "PPAL", "PSYC", "SLST", "SOCI", "SOWK", "SPTH", "STS", "THEA", "THST", "TRAN", "TRAS", "TXLW", "VISA", "WMST"],
["HH", "HLST", "IHST", "KINE", "NURS", "PKIN", "PSYC"],
["LE", "CIVL", "COOP", "EECS", "ENG", "ESSE", "MECH"],
["SB", "ACTG", "ARTM", "BSUS", "DCAD", "ECON", "EMBA", "ENTR", "EXCH", "FINE", "FNEN", "FNSV", "HIMP", "IBUS", "MBA", "INTL", "MACC", "MBAN", "MFIN", "MGMT", "MINE", "MKTG", "MSTM", "OMIS", "ORGS", "OVGS", "PLCY", "PROP", "PUBL", "SGMT", "SOCM"],
["SC", "BC", "BCHM", "BIOL", "BPHS", "CHEM", "COOP", "ENVB", "GEOG", "ISCI", "MATH", "NATS", "PHYS", "SENE", "STS"]
].forEach((arr) => {
let faculty = arr.shift();
FACS.add(faculty);
arr.forEach((subj) => DEPTS.set(subj, faculty));
});
const TOKEN_DELIM_RE = /[^A-Za-z0-9.=]/;
const CRSN_RE = /^[0-9]{4}$/;
const DEPTCRSN_RE = /^([A-Z]{2,4})([0-9]{4})$/;
const CRED_RE = /^(?:Cr=([0-9]{1,2}(?:\.[0-9]{0,2})?)|([0-9]{1,2}\.[0-9]{0,2}))$/;
const MAYBE_CRED_RE = /^[0-9]{1,2}$/;
const MAYBE_DEPT_RE = /^[A-Z]{2,4}$/;
const IGNORE_RE = /^[A-Z]$/;
let ycq_storage = JSON.parse(localStorage.ycq || "{}");
if (!ycq_storage)
ycq_storage = {};
ycq_storage.course_creds = ycq_storage.course_creds || {};
ycq_storage.course_subjs = ycq_storage.course_subjs || {};
let now = new Date();
let month = now.getMonth();
// change to next summer on new year
// begin next FW on July 1
let fw_year, s_year;
if (month >= 6) {
fw_year = now.getFullYear();
} else {
fw_year = now.getFullYear() - 1;
}
s_year = now.getFullYear();
let fw_sess = document.createElement("option");
let fw_sess_val = "FW " + fw_year;
fw_sess.value = fw_sess_val;
fw_sess.textContent = `Fall/Winter ${fw_year}-${fw_year+1}`;
let s_sess = document.createElement("option");
let s_sess_val = "SU " + (s_year - 1);
s_sess.value = s_sess_val;
s_sess.textContent = `Summer ${s_year}`;
switch (ycq_storage.sess) {
case fw_sess_val: fw_sess.selected = true; break;
case s_sess_val: s_sess.selected = true; break;
default:
/* assume enrolling for summer courses between March and May inclusive */
if (month >= 2 && month <= 4)
s_sess.selected = true;
else
fw_sess.selected = true;
}
let ENGLISH_TYPES = {"fac": "faculty", "subj": "subject/subject", "crsn": "course number", "cred": "credit number", "sess": "session (pick on the right)"};
function ready() {
let ywhAd = document.getElementById("ywh-ad");
if (location.protocol != "http:" && location.protocol != "https:" && location.protocol != "file:") {
ywhAd.style.display = "none";
}
let sessions = document.querySelector("#sessions");
sessions.appendChild(fw_sess);
sessions.appendChild(s_sess);
let input = document.getElementById("input");
let link = document.getElementById("link");
let linkContainer = document.getElementById("link-container");
let state;
let apply = function () {
state = {subj: "", fac: "", crsn: "", cred: ""};
let multiple = new Set();
let warn = [], error = [];
let got = function (type, token) {
if (state[type])
multiple.add(ENGLISH_TYPES[type]);
state[type] = token;
};
let tryParse = function (token) {
let subjcrsn, cred;
if (DEPTS.has(token)) {
got("subj", token);
} else if (FACS.has(token)) {
got("fac", token);
} else if ((subjcrsn = DEPTCRSN_RE.exec(token))) {
got("subj", subjcrsn[1]);
got("crsn", subjcrsn[2]);
} else if ((cred = CRED_RE.exec(token))) {
got("cred", parseFloat(cred[1] || cred[2]).toFixed(2));
} else if (CRSN_RE.test(token)) {
got("crsn", token);
} else if (MAYBE_CRED_RE.test(token)) {
got("cred", parseFloat(token).toFixed(2));
warn.push(`assuming ${token} is the number of credits`);
} else if (MAYBE_DEPT_RE.test(token)) {
state.maybeSubj = token;
} else if (!IGNORE_RE.test(token)) {
return false;
}
return true;
};
input.value.split(TOKEN_DELIM_RE).forEach(function (token) {
if (!token || tryParse(token) || tryParse(token.toUpperCase()))
return;
warn.push("don't understand search term: " + token);
});
if (!state.subj && state.maybeSubj) {
state.subj = state.maybeSubj;
warn.push("guessing subject is " + state.maybeSubj);
}
if (!state.subj && ycq_storage.course_subjs[state.crsn]) {
state.subj = ycq_storage.course_subjs[state.crsn];
warn.push(`using saved subject for ${state.crsn}: ${state.subj}`);
}
if (!state.fac && state.subj) {
state.fac = DEPTS.get(state.subj);
if (!state.fac)
error.push("no faculty provided and unknown subject");
}
if (state.subj && state.crsn && !state.cred) {
if (ycq_storage.course_creds[state.subj + state.crsn]) {
state.cred = ycq_storage.course_creds[state.crsn];
warn.push(`using saved credit number for ${state.subj} ${state.crsn}: ${state.cred}`);
} else {
state.cred = "3.00";
warn.push("assuming the number of credits is 3.00");
}
}
let r_sess = document.getElementById("sessions").value;
let sess = r_sess.split(" ");
state.sess = sess[0];
state.year = parseInt(sess[1], 10);
if (state.fac && state.subj && state.crsn && state.cred && state.year && state.sess) {
link.href = `https://w2prod.sis.yorku.ca/Apps/WebObjects/cdm.woa/wa/crsq?fa=${state.fac}&sj=${state.subj}&cn=${state.crsn}&cr=${state.cred}&ay=${state.year}&ss=${state.sess}`;
link.textContent = `York University: ${state.fac}/${state.subj} ${state.crsn} ${state.cred} (${sessions.selectedOptions[0].textContent})`;
linkContainer.style.display = "block";
} else if (state.fac && state.subj && state.sess) {
link.href = `https://w2prod.sis.yorku.ca/Apps/WebObjects/cdm.woa/wa/crsq1?faculty=${state.fac}&subject=${state.subj}&academicyear=${state.year}&studysession=${state.sess}`;
link.textContent = `York University: ${state.fac}/${state.subj} Courses (${sessions.selectedOptions[0]. textContent})`;
linkContainer.style.display = "block";
} else {
linkContainer.style.display = "none";
error.push("insufficient search parameters. need at least subject. see examples above");
}
if (multiple.size)
warn.push("multiple terms for " + Array.from(multiple.values()).join(", ") + ", using last occurrence for each");
document.getElementById("warning").innerHTML = warn.map(w => 'warning: ' + w).join("
");
document.getElementById("error").innerHTML = error.map(e => 'error: ' + e).join("
");
ycq_storage.sess = r_sess;
localStorage.ycq = JSON.stringify(ycq_storage);
};
input.addEventListener("input", apply);
sessions.addEventListener("change", apply);
document.getElementById("sample-queries").addEventListener("click", function (e) {
if (e.target.tagName == "A") {
e.preventDefault();
input.select();
// doesn't work in Firefox, oh well
if (!document.execCommand || !document.execCommand("insertText", false, e.target.textContent))
input.value = e.target.textContent;
apply();
input.focus();
}
});
let save_crsn = function () {
let modified = false;
if (state.crsn) {
if (state.subj && state.cred) {
ycq_storage.course_creds[state.subj + state.crsn] = state.cred;
modified = true;
}
if (state.subj) {
ycq_storage.course_subjs[state.crsn] = state.subj;
modified = true;
}
}
if (modified)
localStorage.ycq = JSON.stringify(ycq_storage);
};
link.addEventListener("click", save_crsn);
document.forms[0].addEventListener("submit", function (e) {
e.preventDefault();
if (linkContainer.style.display == "block")
link.click();
});
input.addEventListener("keydown", function (e) {
if (e.key == "Enter") {
e.preventDefault();
if (linkContainer.style.display == "block") {
// firefox silently ignores simulated link events with modifiers
if (/(?:Firefox|Gecko)\//.test(navigator.userAgent) && (e.ctrlKey || e.shiftKey || e.altKey || e.metaKey)) {
if (e.ctrlKey) {
link.target = "_blank";
link.click();
link.target = "";
} else if (e.shiftKey) {
// only need save_crsn here because other methods already trigger the link click event
save_crsn();
window.open(link.href, "_blank",
"noopener,width=625,resizable,menubar,toolbar,location,personalbar,status,scrollbars");
} else {
link.click();
}
} else {
link.dispatchEvent(new MouseEvent("click", e));
}
}
}
});
apply();
}
if (document.readyState === "interactive" || document.readyState === "complete") {
ready();
} else {
document.addEventListener("DOMContentLoaded", ready);
}
}());