console.log(`UT Registration Plus is running on this page: ${window.location.href}`); var curr_course = {} var semester_code = new URL(window.location.href).pathname.split('/')[4]; var done_loading = true; var next = $("#next_nav_link"); if (next) { chrome.storage.sync.get('loadAll', function (data) { if (data.loadAll) $('[title*="next listing"]').remove(); }); } //This extension may be super lit, but you know what's even more lit? //Matthew Tran's twitter and insta: @MATTHEWTRANN and @matthew.trann if (document.querySelector('#fos_fl')) { let params = (new URL(document.location)).searchParams; let dep = params.get("fos_fl"); let level = params.get("level"); if (dep && level) { if (dep.length == 3 && (level == 'U' || level == 'L' || level == 'G')) { document.querySelector('#fos_fl').value = dep; document.querySelector('#level').value = level; } } } //make heading and modal if (!$("#kw_results_table").length) { $("table").after(Template.Catalog.loading()); $("#container").prepend(Template.Main.modal()); $("#myModal").prepend("
save course popup...
"); // now add to the table $("table thead th:last-child").after('Plus'); $('table').find('tr').each(function () { if (!($(this).find('td').hasClass("course_header")) && $(this).has('th').length == 0) { $(this).append(Template.Main.extension_button()); } }); } if(isIndividualCoursePage()){ chrome.runtime.sendMessage({ command: "shouldOpen", }, function (response) { if(response.open){ $("#distButton").click(); } }); } updateListConflictHighlighting(); $("body").on('click', '#distButton', function () { var row = $(this).closest('tr'); $('.modal-content').stop().animate({ scrollTop: 0 }, 500); $(this).blur(); curr_course = getCourseInfo(row); getDistribution(curr_course); }); function updateLinks(course_info, first_name) { let { prof_name, number } = course_info; course_info["first_name"] = first_name; course_info["links"]["rate_my_prof"] = `http://www.ratemyprofessors.com/search.jsp?queryBy=teacherName&schoolName=university+of+texas+at+austin&queryoption=HEADER&query=${first_name} ${prof_name};&facetSearch=true`; course_info["links"]["ecis"] = profname ? `http://utdirect.utexas.edu/ctl/ecis/results/index.WBX?&s_in_action_sw=S&s_in_search_type_sw=N&s_in_search_name=${prof_name}%2C%20${first_name}` : `http://utdirect.utexas.edu/ctl/ecis/results/index.WBX?s_in_action_sw=S&s_in_search_type_sw=C&s_in_max_nbr_return=10&s_in_search_course_dept=${department}&s_in_search_course_num=${number}`; } function buildCourseLinks(course_info) { let { department, number, unique, prof_name } = course_info links = { "textbook": `https://www.universitycoop.com/adoption-search-results?sn=${semester_code}__${department}__${number}__${unique}`, "syllabi": `https://utdirect.utexas.edu/apps/student/coursedocs/nlogon/?semester=&department=${department}&course_number=${number}&course_title=&unique=&instructor_first=&instructor_last=${prof_name}&course_type=In+Residence&search=Search`, //default ones (before first name can be used) "rate_my_prof": "http://www.ratemyprofessors.com/campusRatings.jsp?sid=1255", "ecis": "http://utdirect.utexas.edu/ctl/ecis/results/index.WBX?" } course_info["links"] = links; return course_info; } function buildBasicCourseInfo(row, course_name, individual) { let { name, department, number } = seperateCourseNameParts(course_name); let instructor_text = $(row).find('td[data-th="Instructor"]').text(); let has_initial = instructor_text.indexOf(',') > 0; course_info = { "full_name": course_name, "name": name, "department": department, "number": number, "individual": individual ? individual : $(row).find('td[data-th="Unique"] a').prop('href'), "register": $(row).find('td[data-th="Add"] a').prop('href'), "unique": $(row).find('td[data-th="Unique"]').text(), "status": $(row).find('td[data-th="Status"]').text(), "prof_name": instructor_text ? has_initial ? capitalizeString(instructor_text.split(', ')[0]) : capitalizeString(instructor_text) : "Undecided", "initial": instructor_text && has_initial ? instructor_text.split(', ')[1].substring(0, 1) : "", "time_data": { "days": $(row).find('td[data-th="Days"]>span').toArray().map(x => $(x).text().trim()), "times": $(row).find('td[data-th="Hour"]>span').toArray().map(x => $(x).text().trim()), "places": $(row).find('td[data-th="Room"]>span').toArray().map(x => $(x).text().trim()) }, "links": {} } return buildCourseLinks(course_info); } /*For a row, get all the course information and add the date-time-lines*/ function getCourseInfo(row) { let course_name = ""; let course_row = {} let individual = undefined; if (isIndividualCoursePage()) { course_name = $("#details h2").text(); course_row = $('table'); individual = document.URL; } else { $('table').find('tr').each(function () { if ($(this).find('td').hasClass("course_header")) { course_name = $(this).find('td').text() + ""; } if ($(this).is(row)) { course_row = row; return false; } }); } curr_course = buildBasicCourseInfo(course_row, course_name, individual); getDescription(curr_course); return curr_course; } function saveCourse() { console.log(curr_course); console.log(JSON.stringify(curr_course)); let { full_name, unique, prof_name, status, individual, register } = curr_course; let dtarr = getDayTimeArray(undefined, curr_course); var c = new Course(full_name, unique, prof_name, dtarr, status, individual, register); chrome.runtime.sendMessage({ command: "courseStorage", course: c, action: $("#saveCourse").val() }, function (response) { $("#saveCourse").text(response.label); $("#saveCourse").val(response.value); $("#snackbar").text(response.done); toggleSnackbar(); chrome.runtime.sendMessage({ command: "updateCourseList" }); }); } /* Update the course list to show if the row contains a course that conflicts with the saved course is one of the saved courses */ function updateListConflictHighlighting(start = 0) { chrome.storage.sync.get('courseConflictHighlight', function (data) { let canHighlight = data.courseConflictHighlight; $('table').find('tr').each(function (i) { if (i >= start) { if (!($(this).find('td').hasClass("course_header")) && $(this).has('th').length == 0) { var unique = $(this).find('td[data-th="Unique"]').text(); chrome.runtime.sendMessage({ command: "isSingleConflict", dtarr: getDayTimeArray(this), unique: unique }, (response) => { let { isConflict, alreadyContains } = response updateTextHighlighting($(this).find('td'), canHighlight, isConflict, alreadyContains); }); } } }); }); } function updateTextHighlighting(tds, canHighlight, isConflict, alreadyContains) { let current_color = rgb2hex(tds.css('color')); if (isConflict && canHighlight && !alreadyContains) { if (current_color != Colors.highlight_conflict) tds.css('color', Colors.highlight_conflict).css('text-decoration', 'line-through').css('font-weight', 'normal'); } else if (!alreadyContains) { if (tds.css('color') != Colors.highlight_default) tds.css('color', Colors.highlight_default).css('text-decoration', 'none').css('font-weight', 'normal'); } if (alreadyContains) { if (tds.css('color') != Colors.highlight_saved) tds.css('color', Colors.highlight_saved).css('text-decoration', 'none').css('font-weight', 'bold'); } } /* For a row, get the date-time-array for checking conflicts*/ function getDayTimeArray(row, course_info) { var day_time_array = [] let days = course_info ? course_info["time_data"]["days"] : $(row).find('td[data-th="Days"]>span').toArray().map(x => $(x).text().trim()); let times = course_info ? course_info["time_data"]["times"] : $(row).find('td[data-th="Hour"]>span').toArray().map(x => $(x).text().trim()); let places = course_info ? course_info["time_data"]["places"] : $(row).find('td[data-th="Room"]>span').toArray().map(x => $(x).text().trim()); for (var i = 0; i < days.length; i++) { let date = days[i]; let time = times[i]; let place = places[i]; for (var j = 0; j < date.length; j++) { let letter = date.charAt(j); if (letter == "T" && j < date.length - 1 && date.charAt(j + 1) == "H") { day_time_array.push(["TH", convertTime(time), place]); } else { if (letter != "H") day_time_array.push([letter, convertTime(time), place]); } } } return day_time_array; } function convertDateTimeArrToLine(date, time, place) { let arr = seperateDays(date) let output = prettifyDaysText(arr) let building = place.substring(0, place.search(/\d/) - 1); building = building ? building : "Undecided Location"; return `${output} at ${time.replace(/\./g, '').replace(/\-/g, ' to ')} in ${building}`; } function badData(course_data, res) { return typeof res == 'undefined' || course_data["prof_name"] == "Undecided"; } /*Query the grades database*/ function getDistribution(course_data, sem) { toggleChartLoading(true); let query = buildQuery(course_data, sem); chrome.runtime.sendMessage({ command: "gradesQuery", query: query }, function (response) { var res = response.data; if (!sem) { openDialog(course_data, res); } else { var data = badData(course_data, res) ? [] : res.values[0]; setChart(data); } }); } function buildTitle(course_data) { return `${course_data["name"]} (${course_data["department"]} ${course_data["number"]})` } function buildTimeTitle(course_info) { $("h2.dateTimePlace").remove(); let { days, times, places } = course_info["time_data"] var lines = []; for (let i = 0; i < days.length; i++) { var date = days[i]; var time = times[i]; var place = places[i]; lines.push($(`

${convertDateTimeArrToLine(date, time, place)}`)); } return lines; } function buildProfTitle(course_data) { const { initial, prof_name } = course_data; return `with ${initial?initial+". ":""}${prof_name}`; } function buildSemestersDropdown(course_data, res) { $("#semesters").empty(); if (badData(course_data, res)) { $("#semesters").append("") } else { var semesters = res.values[0][18].split(","); semesters.sort(semesterSort); semesters.reverse().unshift('Aggregate'); var sems = []; for (var i = 0; i < semesters.length; i++) { sems.push($(``)); } $("#semesters").append(sems); } } function displayBasicCourseInfo(course_info){ $("#title").text(buildTitle(course_info)) $("#topbuttons").before(buildTimeTitle(course_info)); $("#profname").text(buildProfTitle(course_info)); $("#myModal").fadeIn(Timing.fade_time); console.log(course_info); } /*Open the modal and show all the data*/ function openDialog(course_info, res) { displayBasicCourseInfo(course_info); //initial text on the "save course button" chrome.runtime.sendMessage({ command: "alreadyContains", unique: course_info["unique"] }, function (response) { let button_text = response.alreadyContains ? "Remove Course -" : "Add Course +"; let button_val = response.alreadyContains ? "remove" : "add"; $("#saveCourse").text(button_text); $("#saveCourse").val(button_val); }); buildSemestersDropdown(course_info, res) var data = [] if (!badData(course_info, res)) data = res.values[0]; allowClosing(); setChart(data); } function setChart(data) { // set up the chart toggleChartLoading(false); Highcharts.chart('chart', buildChartConfig(data), function (chart) { // on complete if (data.length == 0) { //if no data, then show the message and hide the series chart.renderer.text('Could not find data for this Instructor teaching this Course.', 100, 120) .css({ fontSize: '20px', width: '300px', align: 'center', left: '160px' }) .add(); $.each(chart.series, function (i, ser) { ser.hide(); }); } }); } var error_message = "

You have been logged out. Please refresh the page and log back in using your UT EID and password.

"; function buildFormattedDescription(description_lines) { let description = "" for (let i in description_lines) { let sentence = description_lines[i]; if (sentence.indexOf("Prerequisite") == 0) sentence = `
  • ${sentence}
  • `; else if (sentence.indexOf("May be") >= 0) sentence = `
  • ${sentence}
  • `; else if (sentence.indexOf("Restricted to") == 0) sentence = `
  • ${sentence}
  • `; else sentence = `
  • ${sentence}
  • `; description += sentence; } if (!description) description = error_message; return description; } function extractFirstName(response_node) { let full_name = response_node.find('td[data-th="Instructor"]').text().split(', '); let first = full_name[full_name.length - 1]; first = first.indexOf(' ') > 0 ? first.split(' ')[0] : first; return capitalizeString(first); } function displayDescription(description) { toggleDescriptionLoading(false); $("#description").animate({ 'opacity': 0 }, 200, function () { $(this).html(description).animate({ 'opacity': 1 }, 200); }); } /*Get the course description from the profurl and highlight the important elements, as well as set the eCIS, and rmp links.*/ function getDescription(course_info) { toggleDescriptionLoading(true); $.ajax({ url: course_info["individual"], success: function (response) { if (response) { let response_node = htmlToNode(response); description_lines = response_node.find('#details > p').toArray().map(x => $(x).text()); displayDescription(buildFormattedDescription(description_lines)); let first_name = extractFirstName(response_node); updateLinks(course_info, first_name); } else { displayDescription(error_message); } } }); } function loadNextPages() { chrome.storage.sync.get('loadAll', function (data) { if (data.loadAll) { let link = next.prop('href'); if (done_loading && next && link) { toggleLoadingPage(true); $.get(link, function (response) { if (response) { var next_page = htmlToNode(response); var current = $('tbody'); var old_length = $('tbody tr').length; var last = current.find('.course_header>h2:last').text(); next = next_page.find("#next_nav_link"); toggleLoadingPage(false); var new_rows = []; next_page.find('tbody>tr').each(function () { let has_course_header = $(this).find('td').hasClass("course_header"); if (!(has_course_header && $(this).has('th').length == 0)) $(this).append(Template.Main.extension_button()); if (!(has_course_header && last == $(this).find('td').text())) new_rows.push($(this)); }); current.append(new_rows); updateListConflictHighlighting(old_length + 1) } }).fail(function () { toggleLoadingPage(false); $("#retrylabel").css('display', 'inline-block'); $('#retry').css('display', 'inline-block'); }); } } }); } $("#myModal").on('click', '#saveCourse', function () { setTimeout(function () { saveCourse(); }, 0); }); $("#Syllabi").click(function () { setTimeout(function () { window.open(curr_course["links"]["syllabi"]); }, Timing.button_delay); }); $("#rateMyProf").click(function () { setTimeout(function () { window.open(curr_course["links"]["rate_my_prof"]); }, Timing.button_delay); }); $("#eCIS").click(function () { setTimeout(function () { window.open(curr_course["links"]["ecis"]); }, Timing.button_delay); }); $("#textbook").click(function () { setTimeout(function () { window.open(curr_course["links"]["textbook"]); }, Timing.button_delay); }); $("#semesters").on('change', function () { let sem = $(this).val(); sem = sem == "Aggregate" ? undefined : sem; getDistribution(curr_course, sem); }); $("#retry").click(function () { $("#retrylabel").hide(); $(this).hide(); loadNextPages(); }); function toggleLoadingPage(loading) { if (loading) { done_loading = false; $('#loader').css('display', 'inline-block'); $("#nextlabel").css('display', 'inline-block'); } else { done_loading = true; $('#loader').hide(); $("#nextlabel").hide(); } } function toggleChartLoading(loading) { if (loading) { $('#chartload').css('display', 'inline-block'); $("#chart").hide(); } else { $('#chartload').hide(); $("#chart").show(); } } function toggleDescriptionLoading(loading) { if (loading) { $('#descload').css('display', 'inline-block'); } else { $('#descload').hide(); } } function toggleSnackbar() { setTimeout(function () { $("#snackbar").attr("class", "show"); }, 200); setTimeout(function () { $("#snackbar").attr("class", ""); }, 3000); } function allowClosing() { $('.close').click(function () { close(); }); $('#myModal').click(function (event) { if (event.target.id == 'myModal') { close(); } }); } function close() { $("#myModal").fadeOut(Timing.fade_time); $("#snackbar").attr("class", ""); } /*Listen for update mssage coming from popup or calendar or other course catalog pages*/ chrome.runtime.onMessage.addListener( function (request, sender, sendResponse) { if (request.command == "updateCourseList") { updateListConflictHighlighting(0); } } ); $(document).keydown(function (e) { /*Close Modal when hit escape*/ if (e.keyCode == 27) { close(); } else if (e.keyCode == 13 && $('#myModal').is(':visible')) { saveCourse(); } }); $(window).scroll(function () { if ($(document).height() <= $(window).scrollTop() + $(window).height() + 150) loadNextPages(); });