summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--index.html5
-rw-r--r--script.js101
-rw-r--r--style.css2
3 files changed, 51 insertions, 57 deletions
diff --git a/index.html b/index.html
index 81f9e6f..9dcd56f 100644
--- a/index.html
+++ b/index.html
@@ -20,7 +20,7 @@
<a href="#" class="sample-query">biol</a>,
<a href="#" class="sample-query">SB/ACTG 2010 3.00</a>,
<a href="#" class="sample-query">adms 1000 3</a>,
- <a href="#" class="sample-query">LE EECS 3000 Cr=3.00 A Term:F Professional Practice in Computing</a>
+ <a href="#" class="sample-query">LE EECS 1012 Cr=3.00 A Term:F Net-centric Introduction to Computing</a>
</span>
</div>
<div>
@@ -47,6 +47,9 @@
<hr style="margin: 2em auto; width: 80%;">
<div>
<p>
+ This is an unofficial York University Course Query URL generator. Put in course numbers or subjects and it will spit out a persistent link (none of that "You have exceeded the maximum time limit" after 30 minutes or whatever it is). Despite the word "search" appearing sometimes, <strong>this does not search course names</strong>. Sorry, there's no public API for that. Please send complaints about the non-existence of useful APIs to the Registrar's Office. If <em>this</em> page is broken, please send mail to alex at this domain (alxu dot ca).
+ </p>
+ <p>
Tips:
<ul>
<li id="ywh-ad">it is highly recommended to install YorkU Web Helper, available <a href="">for Firefox</a> and <a href="">for Chrome</a>.</li>
diff --git a/script.js b/script.js
index 6c74539..c9ad800 100644
--- a/script.js
+++ b/script.js
@@ -197,7 +197,6 @@ 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-Za-z]$/; // note: this has to be lowercase, otherwise "ignored search terms" will incorrectly uppercase the input
function parse_ycq_s(str) {
let ycq_s = JSON.parse(str || "{}");
@@ -240,15 +239,21 @@ switch (cached_ycq_s.sess) {
fw_sess.selected = true;
}
-let ENGLISH_TYPES = {"fac": "faculty", "subj": "subject", "crsn": "course number", "cred": "credit number"};
+let ENGLISH_TYPES = {
+ "fac": "faculty",
+ "subj": "subject",
+ "crsn": "course number",
+ "cred": "credit number"
+};
function ready() {
- let ywhAd = document.getElementById("ywh-ad");
- if (location.protocol != "http:" && location.protocol != "https:" && location.protocol != "file:") {
- ywhAd.style.display = "none";
+ // when embedded in the webextension, the protocol will be moz-extension://
+ // or chrome:// or something like that
+ if (!/^(?:https?|file):$/.test(location.protocol)) {
+ document.getElementById("ywh-ad").style.display = "none";
}
- let sessions = document.querySelector("#sessions");
+ let sessions = document.getElementById("sessions");
sessions.appendChild(fw_sess);
sessions.appendChild(s_sess);
@@ -258,19 +263,19 @@ function ready() {
let state;
- let apply_list = function (n, l) {
- if (l.length) {
- document.getElementById(n).style.display = "block";
- document.getElementById(n + "-list").innerHTML = l.map(s => `<li>${s}</li>`).join('');
- } else {
- document.getElementById(n).style.display = "none";
- }
+ let add_li = function (l, t) {
+ var e = document.createElement("li");
+ e.innerHTML = t;
+ l.appendChild(e);
};
let apply = function () {
state = {subj: "", fac: "", crsn: "", cred: ""};
let multiple = new Set();
- let warn = [], error = [];
+ let curWarn = document.getElementById("warning-list");
+ let warn = curWarn.cloneNode(false);
+ let curError = document.getElementById("error-list");
+ let error = curError.cloneNode(false);
let got = function (type, token) {
if (state[type])
@@ -278,8 +283,6 @@ function ready() {
state[type] = token;
};
- let ignored_tokens = [];
-
let tryParse = function (token) {
let subjcrsn, cred;
if (SUBJS.hasOwnProperty(token)) {
@@ -295,11 +298,9 @@ function ready() {
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`);
+ add_li(warn, `assuming ${token} is the number of credits`);
} else if (MAYBE_DEPT_RE.test(token)) {
state["maybeSubj"] = token;
- } else if (IGNORE_RE.test(token)) {
- ignored_tokens.push(token);
} else {
return false;
}
@@ -312,29 +313,20 @@ function ready() {
return;
unk_tokens.push(token);
});
- if (unk_tokens.length) {
- let dont_understand = unk_tokens.map(t => `"${t}"`).join(', ');
- warn.push(`don't understand search terms: ${dont_understand}.`);
- }
-
- if (ignored_tokens.length) {
- let ignored_terms = ignored_tokens.map(t => `"${t}"`).join(', ');
- warn.push(`ignored search terms: ${ignored_terms}.`);
- }
if (!state["subj"] && state["maybeSubj"]) {
state["subj"] = state["maybeSubj"];
- warn.push(`guessing subject is "${state["maybeSubj"]}".`);
+ add_li(warn, `guessing subject is "${state["maybeSubj"]}".`);
}
if (!state["subj"] && state["crsn"] && cached_ycq_s.course_subjs[state["crsn"]]) {
state["subj"] = cached_ycq_s.course_subjs[state["crsn"]];
- warn.push(`assuming ${state["crsn"]} means ${state["subj"]} ${state["crsn"]}, because you last used ${state["subj"]} for ${state["crsn"]}.`);
+ add_li(warn, `assuming ${state["crsn"]} means ${state["subj"]} ${state["crsn"]}, because you last used ${state["subj"]} for ${state["crsn"]}.`);
}
if (!state["subj"] && cached_ycq_s.default_subj) {
state["subj"] = cached_ycq_s.default_subj;
- warn.push(`using ${state["subj"]}, because that was your most recently searched subject.`);
+ add_li(warn, `using ${state["subj"]}, because that was your most recently queried subject.`);
}
if (!state["fac"] && state["subj"]) {
@@ -350,7 +342,7 @@ function ready() {
if (compat_facs) {
let other_facs = compat_facs
.filter(f => f != state["fac"])
- .map(f => `<a href="#" class="prepend-query">${f}</a>`)
+ .map(f => `<a href="#" class="prepend-query">${f}/${state["subj"]}</a>`)
.join(", ");
if (other_facs.length)
return "other options: " + other_facs;
@@ -361,11 +353,11 @@ function ready() {
// 1. most recent faculty for this course
if (state["crsn"] && cached_ycq_s.course_facs[state["subj"] + state["crsn"]]) {
state["fac"] = cached_ycq_s.course_facs[state["subj"] + state["crsn"]];
- warn.push(`assuming ${state["subj"]} ${state["crsn"]} is ${state["fac"]}/${state["subj"]}, because you last used ${state["fac"]} for ${state["subj"]} ${state["crsn"]}. ${other_options()}`);
+ add_li(warn, `assuming ${state["subj"]} ${state["crsn"]} is ${state["fac"]}/${state["subj"]}, because you last used ${state["fac"]} for ${state["subj"]} ${state["crsn"]}. ${other_options()}`);
} else if (cached_ycq_s.subj_facs[state["subj"]]) {
// 2. most recent faculty for this subject
state["fac"] = cached_ycq_s.subj_facs[state["subj"]];
- warn.push(`assuming ${state["subj"]} means ${state["fac"]}/${state["subj"]}, because you last used ${state["fac"]} for ${state["subj"]}. ${other_options()}`);
+ add_li(warn, `assuming ${state["subj"]} means ${state["fac"]}/${state["subj"]}, because you last used ${state["fac"]} for ${state["subj"]}. ${other_options()}`);
} else if (compat_facs) {
// 3. most recent compatible faculty
if (cached_ycq_s.default_facs)
@@ -374,24 +366,27 @@ function ready() {
state["fac"] = cached_ycq_s.default_facs[i];
if (state["fac"]) {
- warn.push(`assuming ${state["subj"]} means ${state["fac"]} ${state["subj"]}, because you recently used ${state["fac"]}. ${other_options()}`);
+ add_li(warn, `assuming ${state["subj"]} means ${state["fac"]}/${state["subj"]}, because you recently used ${state["fac"]}. ${other_options()}`);
} else {
// 4. first compatible faculty
state["fac"] = compat_facs[0];
- warn.push(`assuming ${state["subj"]} means ${state["fac"]} ${state["subj"]}, because ${state["fac"]} is the default for ${state["subj"]}. ${other_options()}`);
+ if (compat_facs.length > 1)
+ add_li(warn, `assuming ${state["subj"]} means ${state["fac"]}/${state["subj"]}, because we set that as the default for ${state["subj"]}. ${other_options()}`);
+ else
+ add_li(warn, `assuming ${state["subj"]} means ${state["fac"]}/${state["subj"]}, because we only know ${state["fac"]} for ${state["subj"]}.`);
}
} else {
- error.push("no faculty provided and unknown subject");
+ add_li(error, "no faculty provided and unknown subject");
}
}
if (state["subj"] && state["crsn"] && !state["cred"]) {
if (cached_ycq_s.course_creds[state["subj"] + state["crsn"]]) {
state["cred"] = cached_ycq_s.course_creds[state["subj"] + state["crsn"]];
- warn.push(`assuming ${state["subj"]} ${state["crsn"]} is ${state["cred"]} credits, because you last used ${state["cred"]} for ${state["subj"]} ${state["crsn"]}.`);
+ add_li(warn, `assuming ${state["subj"]} ${state["crsn"]} is ${state["cred"]} credits, because you last used ${state["cred"]} for ${state["subj"]} ${state["crsn"]}.`);
} else {
state["cred"] = "3.00";
- warn.push("assuming the number of credits is 3.00, because that's the most common number.");
+ add_li(warn, "assuming the number of credits is 3.00, because that's the most common number.");
}
}
@@ -409,14 +404,16 @@ function ready() {
linkContainer.style.display = "block";
} else {
linkContainer.style.display = "none";
- error.push("need at least subject. see examples above");
+ add_li(error, "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");
+ add_li(warn, "multiple terms for " + Array.from(multiple.values()).join(", ") + ", using last occurrence for each");
- apply_list("warning", warn);
- apply_list("error", error);
+ curWarn.parentNode.replaceChild(warn, curWarn);
+ curError.parentNode.replaceChild(error, curError);
+ document.getElementById("warning").style.display = warn.children.length ? "block" : "none";
+ document.getElementById("error").style.display = error.children.length ? "block" : "none";
};
input.addEventListener("input", apply);
sessions.addEventListener("change", apply);
@@ -462,17 +459,13 @@ function ready() {
if (state["fac"]) {
if (state["crsn"])
new_ycq_s.course_facs[state["subj"] + state["crsn"]] = state["fac"];
-
new_ycq_s.subj_facs[state["subj"]] = state["fac"];
}
-
if (state["crsn"]) {
if (state["cred"])
new_ycq_s.course_creds[state["subj"] + state["crsn"]] = state["cred"];
-
new_ycq_s.course_subjs[state["crsn"]] = state["subj"];
}
-
new_ycq_s.default_subj = state["subj"];
}
@@ -490,25 +483,23 @@ function ready() {
if (linkContainer.style.display == "block")
link.click();
});
- input.addEventListener("blur", save_defaults);
input.addEventListener("keydown", function (e) {
if (e.key == "Enter") {
e.preventDefault();
if (linkContainer.style.display == "block") {
- // firefox silently ignores simulated link events with modifiers
- // use [\/] to fix syntax highlighting
- if (/(?:Firefox|Gecko)[\/]/.test(navigator.userAgent) && (e.ctrlKey || e.shiftKey || e.altKey || e.metaKey)) {
+ // firefox silently ignores simulated link events with keyboard modifiers
+ // this way triggers popup blocker but nothing we can do about it
+ if (navigator.userAgent.indexOf("Firefox/") > -1 && (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 here because other methods already trigger the link click event
+ // note: other methods save by link click listener
// for efficiency, don't save twice
save_defaults();
- window.open(link.href, "_blank",
- "noopener,width=625,resizable,menubar,toolbar,location,personalbar,status,scrollbars");
- } else {
+ window.open(link.href, "_blank", "noopener,width=625,resizable,menubar,toolbar,location,personalbar,status,scrollbars");
+ } else { // dunno what to do
link.click();
}
} else {
diff --git a/style.css b/style.css
index 15cf320..a927dd1 100644
--- a/style.css
+++ b/style.css
@@ -40,7 +40,7 @@ select {
}
#link {
- font-size: 120%;
+ font-size: 1.4em;
}
#error {