Commit a8085f19 authored by Ozer Chagatai's avatar Ozer Chagatai

Merge pull request #97 from SergueiFedorov/Bug-Fix

Bug fix
parents 9ad26ee6 756c36b1
File deleted
.DS_Store
......@@ -9,18 +9,24 @@
//The complete source code is available on: https://github.com/ochagata/rateMyPaul
//The master branch contains the source code shipped with the extention
function GetLoadingArea()
{
return $(".LoadingArea", window.parent.document);
}
function CloseLoadingArea() {
if ($(".LoadingArea").length > 0) {
$(".LoadingArea").remove();
}
if (GetLoadingArea().length > 0) {
GetLoadingArea().remove();
}
}
function CreateLoadingArea() {
if ($(".LoadingArea").length == 0) {
if (GetLoadingArea().length == 0) {
$.get(chrome.extension.getURL("loading.html"), function (html) {
$("Body").append(html);
$(".LoadingArea").append("<img src='" + chrome.extension.getURL('loading.GIF') + "'/>")
$("body", window.parent.document).append(html);
GetLoadingArea().append("<img src='" + chrome.extension.getURL('loading.GIF') + "'/>")
});
}
}
\ No newline at end of file
......@@ -9,18 +9,93 @@
//The complete source code is available on: https://github.com/ochagata/rateMyPaul
//The master branch contains the source code shipped with the extention
function ClosePopup() {
if (PopupIsOpen()) {
$(".RMPDisplayArea").remove();
//Forward binds events. These will apply to any element that will get
//added to the DOM which has the provided ID
$("body", window.parent.document).on("click", "#CloseButton", function () {
$(this).closest(".RMPDisplayArea").remove();
});
$("body").on("click", "#PinButton", function()
{
if ($(this).closest(".RMPDisplayArea").is(".Pinned"))
{
$(this).closest(".RMPDisplayArea").removeClass("Pinned")
$(this).attr("src", chrome.extension.getURL('window-unlocked.png'));
}
else
{
$(this).closest(".RMPDisplayArea").addClass("Pinned");
$(this).attr("src", chrome.extension.getURL('window-locked.png'));
}
});
$("body", window.parent.document).on("drag", ".RMPDisplayArea", function()
{
$(this).addClass("Floating");
});
$("body", window.parent.document).on("click", ".RMPDisplayArea", function()
{
$(".RMPDisplayArea").each(function(index, item)
{
$(this).css("zIndex", 1);
});
$(this).css("zIndex", 999);
});
function CloseAllNoneFloatingPopups()
{
$(".RMPDisplayArea", window.parent.document).each(function(index, item)
{
if ($(item).is(".Floating") == false)
{
ClosePopup(item);
}
});
}
function PopupIsOpen() {
return $(".RMPDisplayArea").length > 0;
function CloseUncessaryPopups()
{
var innerDoc = GetInnerDoc();
$(".RMPDisplayArea").each(function(index, item)
{
if ($(item).is(".Pinned") == false)
{
if (ProfessorNameStillOnPage($(this).find(".ProfessorNameLink").text(), innerDoc) == false)
{
$(this).remove();
}
}
});
}
function CreatePopup(result, profName, pageUrl) {
function CloseAllUnpinnedPopups()
{
$(".RMPDisplayArea", window.parent.document).each(function(index, item)
{
if ($(item).is(".ui-draggable-disabled") == false)
{
ClosePopup(item);
}
});
}
function ClosePopup(popup) {
$(popup).remove();
}
function CreatePopup(result, profName, pageUrl, index) {
function AppendPopupToBody(html)
{
var newPopup = $(html).appendTo($("body", window.parent.document));
$(newPopup).css("right", (index * 330) + 50 )
return newPopup;
}
//Sudo-Constant Vars (no such thing as constants in JavaScript)
var PROFESSOR_NAME_FIELD = /__PROFESSOR_NAME__/g;
var OVERALL_QUALITY_FIELD = /__OVERALL_QUALITY__/g;
......@@ -31,18 +106,9 @@ function PopupIsOpen() {
var LINK_TO_PROFESSOR_PAGE = /__LINK_TO_PROFESSOR_PAGE__/g;
var CLOSE_BUTTON = /__CLOSE_BUTTON__/g;
var LINK_ICON = /__LINK_ICON__/g;
var PIN_ICON = /__PIN_ICON__/g;
var parsedProfessor = null;
var hasData = true;
try {
parsedProfessor = JSON.parse(result);
} catch (err) {
hasData = false;
}
//Remove the loading animation if it's showing
ClosePopup();
// console.log(result);
//If the user keeps clicking, it will open multiple display areas on top of each other
CloseLoadingArea();
......@@ -52,18 +118,33 @@ function PopupIsOpen() {
html = html.replace(CLOSE_BUTTON, chrome.extension.getURL('close.png'));
html = html.replace(LINK_ICON, chrome.extension.getURL('link.png'));
html = html.replace(PIN_ICON, chrome.extension.getURL('window-unlocked.png'));
if (hasData == true) {
if (result.Grades != undefined && result.Ratings != undefined ) {
html = html.replace(PROFESSOR_NAME_FIELD, profName);
html = html.replace(OVERALL_QUALITY_FIELD, parsedProfessor.Grades[0].Rating);
html = html.replace(AVERAGE_GRADE_FIELD, parsedProfessor.Grades[1].Rating);
html = html.replace(OVERALL_QUALITY_FIELD, result.Grades[0].Rating);
html = html.replace(AVERAGE_GRADE_FIELD, result.Grades[1].Rating);
html = html.replace(HELPFULNESS_FIELD, result.Ratings[0].Rating);
html = html.replace(CLARITY_FIELD, result.Ratings[1].Rating);
html = html.replace(EASINESS_FIELD, result.Ratings[2].Rating);
html = html.replace(LINK_TO_PROFESSOR_PAGE, pageUrl);
html = html.replace(HELPFULNESS_FIELD, parsedProfessor.Ratings[0].Rating);
html = html.replace(CLARITY_FIELD, parsedProfessor.Ratings[1].Rating);
html = html.replace(EASINESS_FIELD, parsedProfessor.Ratings[2].Rating);
var popup = AppendPopupToBody(html);
$.each(result.Comments, function(index, item)
{
$.get(chrome.extension.getURL("ReviewSection.html"), function(ReviewHTML)
{
ReviewHTML = ReviewHTML.replace("__COURSE_NUMBER__", item.Class);
ReviewHTML = ReviewHTML.replace("__COURSE_COMMENT__", item.Comment);
$(ReviewHTML).appendTo($("#ratingsTab", popup));
});
});
html = html.replace(LINK_TO_PROFESSOR_PAGE, "http://www.ratemyprofessors.com" + pageUrl);
} else {
......@@ -78,7 +159,12 @@ function PopupIsOpen() {
html = html.replace(EASINESS_FIELD, naString);
html = html.replace(LINK_TO_PROFESSOR_PAGE, "http://www.ratemyprofessors.com/search.jsp?queryoption=HEADER&queryBy=teacherName&query=" + profName);
AppendPopupToBody(html);
}
$("body").append(html);
$(".RMPDisplayArea", window.parent.document).draggable();
$(".RMPMain", window.parent.document).accordion({ heightStyle: "content" });
});
}
\ No newline at end of file
//DISCLAIMRER:
//We, Ozer Chagatai and Serguei Fedorov are not responsible for third party modification, repackaging and redistribution of this source code.
//Please be aware that third party distribution of this extention may contain melicious source code which is beyond our control.
//The source code of RateMyPaul, produced by Ozer Chagatai and Serguei Fedorov does not collect and will never collect student and faculty data protected by FERPA.
//This extention only uses the names of DePaul faculty to produce search results. DePaul faculty names are publicly available both through a guest Campus Connect account
//as well as the public facing DePaul Website.
//The complete source code is available on: https://github.com/ochagata/rateMyPaul
//The master branch contains the source code shipped with the extention
//Controls how the popup get's closed. This is useful if
//the search opens the popup and nullifies the close routine
popupClosureDelegate = null;
(function()
{
setInterval(function()
{
var iframe = document.getElementById('ptifrmtgtframe');
if (iframe != null)
{
var innerDoc = iframe.contentDocument || iframe.contentWindow.document;
if (PopupIsOpen() && popupClosureDelegate != null && popupClosureDelegate($(".ProfessorName")[0].innerText, innerDoc) == false)
{
ClosePopup();
}
}
}, 2000);
})
\ No newline at end of file
//DISCLAIMRER:
//We, Ozer Chagatai and Serguei Fedorov are not responsible for third party modification, repackaging and redistribution of this source code.
//Please be aware that third party distribution of this extention may contain melicious source code which is beyond our control.
//The source code of RateMyPaul, produced by Ozer Chagatai and Serguei Fedorov does not collect and will never collect student and faculty data protected by FERPA.
//This extention only uses the names of DePaul faculty to produce search results. DePaul faculty names are publicly available both through a guest Campus Connect account
//as well as the public facing DePaul Website.
//The complete source code is available on: https://github.com/ochagata/rateMyPaul
//The master branch contains the source code shipped with the extention
function ProcessSearchResults(response, popupDelegate, professorName) {
//Obtain the actual link to the page
var searchResult = JSON.parse(response);
if (searchResult.length == 0) {
//We don't have any data from the web service
popupDelegate(searchResult, professorName, "");
} else {
var pageURL = searchResult[0].URL;
var professorPageURL = 'http://www.sergueifedorov.com/rmpapi/Professor?url=' + pageURL;
chrome.runtime.sendMessage({
method: "GET",
url: professorPageURL
}, function(result) {
popupDelegate(result, professorName, pageURL);
});
}
}
\ No newline at end of file
//DISCLAIMRER:
//We, Ozer Chagatai and Serguei Fedorov are not responsible for third party modification, repackaging and redistribution of this source code.
//Please be aware that third party distribution of this extention may contain melicious source code which is beyond our control.
//The source code of RateMyPaul, produced by Ozer Chagatai and Serguei Fedorov does not collect and will never collect student and faculty data protected by FERPA.
//This extention only uses the names of DePaul faculty to produce search results. DePaul faculty names are publicly available both through a guest Campus Connect account
//as well as the public facing DePaul Website.
function GetElementWithoutChildren(element)
{
return $(element).clone().children().remove().end();
}
function RMPParser()
{
var searchURL = "http://www.ratemyprofessors.com/search.jsp?queryoption=HEADER&queryBy=teacherName&schoolName=DePaul+University&schoolID=1389&query=";
//Removes any HTML that is not necessary
function StripDownHTML(parsedHTML)
{
return $(parsedHTML).find("img").remove().end();
}
function SearchProcessor()
{
this.GetProfessorNames = function(parsedHTML)
{
var returnData = [];
$(parsedHTML).find(".listing").each(function(index, item)
{
returnData.push({ "Name" : $(item).find(".main").text(),
"College" : $(item).find(".sub").text(),
"URL" : $(item).find("a").attr("href")});
});
return returnData;
}
}
function CommentsProcessor()
{
this.GetProfessorReviews = function(parsedHTML)
{
var returnData = [];
//Find the comments td and then look for the closest TR.
//individual reviews don't have a defined class.
$(parsedHTML).find(".comments").each(function(index, item)
{
returnData.push({ "Class" : GetElementWithoutChildren($(this).siblings(".class").find(".name .response")).text(),
"Comment" : $(this).find("p").text().trim()
});
});
return returnData;
}
}
function ReviewPageProcessor()
{
this.GetProfessorGrades = function(parsedHTML)
{
var returnData = [];
$(parsedHTML).find(".breakdown-header").each(function(index, item)
{
returnData.push({ "Label" : GetElementWithoutChildren(item).text().trim(),
"Rating" : $(item).find(".grade").text().trim()
});
});
return returnData;
}
this.GetProfessorRatings = function(parsedHTML)
{
var returnData = [];
//The page returns 6 ratings. Only the first 3 appear to be valid
$(parsedHTML).find(".rating-slider").slice(0, 3).each(function(index, item)
{
returnData.push({ "Label" : $(item).find(".label").text(),
"Rating" : $(item).find(".rating").text()
});
});
return returnData;
}
}
this.getFullProfessorRatings = function(URL, responseCallback)
{
chrome.runtime.sendMessage({
method: "GET",
url: URL
}, function(data) {
if (data == null)
{
throw new Error("Data recieved from RMP is null");
}
data = StripDownHTML(data);
var reviewProcessor = new ReviewPageProcessor();
var ratings = reviewProcessor.GetProfessorRatings(data);
var grades = reviewProcessor.GetProfessorGrades(data);
var commentsProcessor = new CommentsProcessor();
var comments = commentsProcessor.GetProfessorReviews(data);
var res = [];
res.Grades = grades;
res.Ratings = ratings;
res.Comments = comments;
responseCallback(res);
});
}
this.getProfessorSearch = function(name, responseCallback)
{
var searchURLFinal = searchURL + name.split(" ").join("%20");
chrome.runtime.sendMessage({
method: "GET",
url: searchURLFinal
}, function(data) {
if (data == null)
{
throw new Error("Data recieved from RMP is null");
}
data = StripDownHTML(data);
var processor = new SearchProcessor();
var res = processor.GetProfessorNames(data);
responseCallback(res);
return true;
});
}
}
\ No newline at end of file
<div>__COURSE_NUMBER__</div>
<div style="font-size: 12px; padding: 3px;">__COURSE_COMMENT__</div>
\ No newline at end of file
//DISCLAIMRER:
//We, Ozer Chagatai and Serguei Fedorov are not responsible for third party modification, repackaging and redistribution of this source code.
//Please be aware that third party distribution of this extention may contain melicious source code which is beyond our control.
//The source code of RateMyPaul, produced by Ozer Chagatai and Serguei Fedorov does not collect and will never collect student and faculty data protected by FERPA.
//This extention only uses the names of DePaul faculty to produce search results. DePaul faculty names are publicly available both through a guest Campus Connect account
//as well as the public facing DePaul Website.
//The complete source code is available on: https://github.com/ochagata/rateMyPaul
//The master branch contains the source code shipped with the extention
(function()
{
function EVENT_Search_Button_Clicked()
{
var searchValue = $("#SearchInput").val();
if (searchValue.length != 0)
{
var searchUrl = 'http://www.sergueifedorov.com/rmpapi/search/' + $("#SearchInput").val();
ClosePopup();
CreateLoadingArea();
//Global variable
popupClosureDelegate = null;
chrome.runtime.sendMessage({
method: "GET",
url: searchUrl
},
function(response) {
ProcessSearchResults(response, CreatePopup, $("#SearchInput").val());
});
}
}
function ApplyEventHandlers()
{
$("#SearchSubmit").click(EVENT_Search_Button_Clicked);
}
//Stupdily hacky way because the iFrame caseus two different search bars to render
if ($("#ptifrmtgtframe").length != 0)
{
console.log($("#SearchBar").length);
$.get(chrome.extension.getURL('search.html'), function(html)
{
$("body").append(html);
ApplyEventHandlers();
});
}
})();
\ No newline at end of file
//DISCLAIMRER:
//We, Ozer Chagatai and Serguei Fedorov are not responsible for third party modification, repackaging and redistribution of this source code.
//Please be aware that third party distribution of this extention may contain melicious source code which is beyond our control.
//The source code of RateMyPaul, produced by Ozer Chagatai and Serguei Fedorov does not collect and will never collect student and faculty data protected by FERPA.
//This extention only uses the names of DePaul faculty to produce search results. DePaul faculty names are publicly available both through a guest Campus Connect account
//as well as the public facing DePaul Website.
//The complete source code is available on: https://github.com/ochagata/rateMyPaul
//The master branch contains the source code shipped with the extention
function ProfessorNameStillOnPage(professorName, documentToSearch)
{
var professorFound = false;
professorName = professorName.trim();
$.each(documentToSearch.querySelectorAll("span[id ^= 'MTG_INSTR']"), function(index, professor) {
var compareToProfessor = $(professor)[0].innerText;
compareToProfessor = compareToProfessor.trim();
//console.log(professorName + " " + compareToProfessor);
if (compareToProfessor.trim().indexOf(professorName) > -1) {
professorFound = true;
return false; //Returns out of the the each loop
}
});
return professorFound;
}
function GetInnerDoc()
{
var iframe = document.getElementById('ptifrmtgtframe');
var innerDoc = iframe.contentDocument || iframe.contentWindow.document;
return innerDoc;
}
\ No newline at end of file
//displays icon in address bar when script is active
function showPageAction( tabId, changeInfo, tab ) {
if(tab.url.substring(0, 33) == 'https://campusconnect.depaul.edu/'){
chrome.pageAction.show(tabId);
}
chrome.pageAction.show(tabId);
};
chrome.tabs.onUpdated.addListener(showPageAction);
//function to make xmlhttprequests
chrome.runtime.onMessage.addListener(function(request, sender, callback) {
......@@ -19,4 +18,4 @@ chrome.runtime.onMessage.addListener(function(request, sender, callback) {
xhr.open('GET', request.url, true);
xhr.send();
return true; // prevents the callback from being called too early on return
});
\ No newline at end of file
});
This diff is collapsed.
This diff is collapsed.
<link rel="stylesheet" type="text/css" href="loading.css">
<div class="LoadingArea" style="bottom: 30px; right: 30px; position: absolute">
<div class="LoadingArea" style="bottom: 60px; right: 30px; position: absolute">
</div>
\ No newline at end of file
......@@ -12,51 +12,74 @@
//This file relies on:
//LoadingAreaFunctionality.js
//PopupFunctionality.js
//Utilities.js
//Make sure they are imported
(function() {
//Entry point
main();
function main() {
setInterval(AugmentPage, 3000);
}
function ProfessorNameStillOnPage(professorName, documentToSearch)
$("body").on("click", ".ratingButton", function()
{
var professorFound = false;
$.each(documentToSearch.querySelectorAll("span[id ^= 'MTG_INSTR']"), function(index, professor) {
var compareToProfessor = $(professor)[0].innerText;
compareToProfessor = compareToProfessor.replace(/'/g, "");
if (professorName === compareToProfessor) {
professorFound = true;
return false; //Returns out of the the each loop
var profName = $(this).attr('name');
//Close all the popups to make sure the loading animation isn't playing on top of an existing popup
CloseAllNoneFloatingPopups();
//Some names have new lines in them. If that is true, then there either must be more than one
//professor, or the professor name is repeating (usually the case). We only want the first name
var profNameSplit = profName.split(/\n/g);
CreateLoadingArea();
var alreadyExtractedNames = [];
$.each(profNameSplit, function(index, item)
{
var parsedItem = item.replace(/,/g, "").trim();
if (alreadyExtractedNames.indexOf(parsedItem) == -1)
{
//Having spaces in between names can create issues for HTTP GET.
//format them properly
var searchProfString = parsedItem.split(" ").join("%20");
var parser = new RMPParser();
parser.getProfessorSearch(searchProfString, function(data)
{
ProcessSearchResults(data, CreatePopup, parsedItem, index);
});
alreadyExtractedNames.push(parsedItem);
}
});
});
return professorFound;
}
function ProcessSearchResults(response, popupDelegate, professorName) {
function ProcessSearchResults(response, popupDelegate, professorName, index) {
//Obtain the actual link to the page
var searchResult = JSON.parse(response);
//var searchResult = JSON.parse(response);
var searchResult = response;
if (searchResult.length == 0) {
//We don't have any data from the web service
popupDelegate(searchResult, professorName, "");
popupDelegate([], professorName, "", index);
} else {
var pageURL = searchResult[0].URL;
var professorPageURL = 'http://www.sergueifedorov.com/rmpapi/Professor?url=' + pageURL;
chrome.runtime.sendMessage({
method: "GET",
url: professorPageURL
}, function(result) {
popupDelegate(result, professorName, pageURL);
var pageURL = "http://www.ratemyprofessors.com/" + searchResult[0].URL;
var parser = new RMPParser();
parser.getFullProfessorRatings(pageURL, function(data)
{
popupDelegate(data, professorName, pageURL, index);
});
}
}
......@@ -64,44 +87,17 @@
function AugmentPage() {
if (document.getElementById('ptifrmtgtframe') !== null) {
var iframe = document.getElementById('ptifrmtgtframe');
var innerDoc = iframe.contentDocument || iframe.contentWindow.document;
//Close out the popup if the professor's name is no longer there (the search has been updated or you nagivated somewhere else)
if (PopupIsOpen()) {
if (ProfessorNameStillOnPage($(".ProfessorName")[0].innerText, innerDoc) == false)
{
ClosePopup();
}
}
var innerDoc = GetInnerDoc();
CloseUncessaryPopups();
//This line doesn't work for me. It's always 0 : Serguei
if (innerDoc.getElementsByClassName("ratingButton").length == 0) {
$.each(innerDoc.querySelectorAll("span[id ^= 'MTG_INSTR']"), function(index, professor) {
var profName = $(professor)[0].innerText;
if (profName != 'Staff') {
$(professor).append("'<input class='ratingButton' type='button' value='SHOW RATING' />'").click(function() {
//Having spaces in between names can create issues for HTTP GET.
//format them properly
var searchProfString = profName.split(" ").join("%20");
//Does jQuery really not have a param/arg string?
var searchUrl = 'http://www.sergueifedorov.com/rmpapi/search/' + searchProfString;
ClosePopup();
CreateLoadingArea();
chrome.runtime.sendMessage({
method: "GET",
url: searchUrl
},
function(response) {
ProcessSearchResults(response, CreatePopup, profName);
});
});
$(professor).append("<input name='" + profName + "' class='ratingButton' type='button' value='SHOW RATING' />");
}
});
}
......
{
"manifest_version": 2,
"name": "RateMyPaul",
"version": "1.3",
"version": "1.5.1",
"author": "Ozer Chagatai",
"author": "Serguei Fedorov",
"description": "Choose your DePaul courses more efficiently with ratings from RateMyProfessors.com.",
......@@ -13,19 +13,23 @@
},
"permissions": [
"https://www.ratemyprofessors.com/*",
"http://www.ratemyprofessors.com/search.jsp",
"https://campusconnect.depaul.edu/*",
"http://www.sergueifedorov.com/rmpapi/search/"
"declarativeContent"
],
"web_accessible_resources": [
"popup.html",
"loading.html",
"search.html",
"ReviewSection.html",
"loading.GIF",