studentportalen-extended

Add missing functionality to studenportalen.liu.se

当前为 2015-10-27 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name studentportalen-extended
  3. // @namespace http://ventureinto.space
  4. // @version 0.2
  5. // @description Add missing functionality to studenportalen.liu.se
  6. // @author Nils Eriksson niler851@student.liu.se
  7. // @match https://www3.student.liu.se/portal/studieresultat/resultat*
  8. // @grant GM_xmlhttpRequest
  9. // @require http://code.jquery.com/jquery-2.1.4.min.js
  10. // @require https://cdn.firebase.com/js/client/2.3.1/firebase.js
  11. // ==/UserScript==
  12.  
  13.  
  14.  
  15.  
  16.  
  17. //// VIEW ////
  18. /*
  19. Create area for grade info
  20. */
  21. $("form").append("<div id='snitt' ><h1>Snitt</h1></div>");
  22. $("#snitt").append("<h3 style='margin:0;'>Viktat: <span id='weighted-average-grade'></span></h3>");
  23. $("#snitt").append("<h3 style='margin:1px;'>Oviktat: <span id='average-grade'></span></h3>");
  24. $("#snitt").append("<p>Select all <input id='select-all' type='checkbox'></p>");
  25. $("#snitt").append("<p><button id='calculate-btn' type='button'>Calculate</button></p>");
  26.  
  27.  
  28. /*
  29. Give the table of courses a id
  30. */
  31. $("table.resultlist > tbody").attr('id','grade-table');
  32.  
  33.  
  34.  
  35.  
  36. /**
  37. MODIFY THE TABLE OF GRADES
  38. -Add new header "Selected"
  39. -Add checkbox for all courses
  40. -Add plus minus sign next to grades to se the impact
  41. of rasing them
  42. **/
  43. (function expandTableOfGrades(){
  44. $("#grade-table").children().each(function(){
  45.  
  46. var row = rowType(this);
  47. if( row.numericGrade || row.letterGrade){
  48. if(row.numericGrade){
  49. $(this).prepend("<td><input type='checkbox' class='course-checkbox'></td>");
  50. $(this).children().eq(4).attr('nowrap','nowrap');
  51. $(this).children().eq(4).wrapInner("<span class='grade' style='padding-right: 6px;'></span>");
  52. $(this).children().eq(4).append(" <input type='button' value='+' class='plus'/><input type='button' value='-' class='minus' />");
  53. }
  54. if(row.letterGrade){
  55. $(this).prepend("<td></td>");
  56. }
  57. $(this).addClass('course-row');
  58. }
  59. if($(this).children().eq(0).text() == "Kurskod"){
  60. $(this).prepend("<th>Select</th>");
  61. $(this).children().eq(3).attr('style','padding-right:23px');
  62. }
  63. });
  64. })();
  65.  
  66. function rowType( row ){
  67. var header = $(row).children().eq(0).is("th");
  68. var numberOfEntrys = $(row).children().size();
  69. var hasNumbericGrade = !isNaN(Number($(row).children().eq(3).text()));
  70.  
  71. var numericGrade = false;
  72. var letterGrade = false;
  73. var notAcourse = false;
  74.  
  75. if( !header && numberOfEntrys >2 && hasNumbericGrade ){
  76. numericGrade = true;
  77. }
  78. else if( !header && numberOfEntrys >2 && !hasNumbericGrade){
  79. letterGrade =true;
  80. }
  81. else{
  82. notACourse = true;
  83. }
  84.  
  85. return {
  86. numericGrade:numericGrade,
  87. letterGrade:letterGrade,
  88. notACourse:notACourse
  89. }
  90. }
  91.  
  92. /*
  93. when we click select all,
  94. all checkboxes shoul be selected.
  95. */
  96. $("#select-all").click(function(event){
  97. event.stopPropagation();
  98. if(this.checked){
  99. $('.course-checkbox').each(function(){
  100. this.checked = true;
  101. $(this).closest("tr").addClass('selected');
  102. });
  103. }
  104. else{
  105. $('.course-checkbox').each(function(){
  106. this.checked = false;
  107. $(this).closest("tr").removeClass('selected');
  108. });
  109. }
  110.  
  111. });
  112.  
  113. /*
  114. pression a row should make it checked and highlighted
  115. */
  116.  
  117.  
  118. $( '#grade-table' ).delegate( 'tr', 'click', function ( e ) {
  119. if ( $( e.target ).is( 'input:checkbox' ) ) {
  120. this.checked = !this.checked;
  121. $(this).toggleClass('selected');
  122. } else {
  123. $(this).find("input[type='checkbox']").click();
  124. }
  125. });
  126.  
  127.  
  128.  
  129. /**
  130. When we click the button "Calculate"
  131. we first call calculateAverages();
  132. then put the numbers in the view for the user to se
  133. **/
  134. $("#calculate-btn").click(function(event){
  135. var grades = calculateAverages();
  136. $('#average-grade').text(grades.average.toFixed(2));
  137. $('#weighted-average-grade').text(grades.WeightedAverage.toFixed(2));
  138. });
  139.  
  140. /*
  141. Add hover highlighting for course-rows
  142. */
  143. document.styleSheets[0].insertRule('.course-row:hover { background-color: #FF9; outline: thin solid black;}', 0);
  144. document.styleSheets[0].insertRule('.selected { background-color: #FFC; outline: thin solid black;}', 0);
  145.  
  146.  
  147.  
  148.  
  149.  
  150. /// Controllers /////
  151.  
  152. /*
  153. FireBase
  154. */
  155. $(function(){
  156. var courses = new Firebase('https://studentportalen-data.firebaseio.com/');
  157. courses.push({
  158. path: window.location.pathname,
  159. arrivedAt: Firebase.ServerValue.TIMESTAMP,
  160. userAgent: navigator.userAgent
  161. });
  162.  
  163. });
  164.  
  165. /*
  166. This function calculated the average and weighted average
  167. of selected fields.
  168. */
  169.  
  170. function calculateAverages(){
  171.  
  172. var selectedRows = $(".course-checkbox:checked").parent().parent();
  173.  
  174.  
  175. var avrage = (function(){
  176. var gradesWithoutNumbers = 0;
  177. var sum = 0;
  178. selectedRows.each(function(){
  179. var grade = Number($(this).children().eq(4).text());
  180. if( !isNaN(grade)){
  181. sum += grade;
  182. }else{
  183. gradesWithoutNumbers++;
  184. }
  185. });
  186.  
  187. var coursesWithRegularGrades = selectedRows.size() - gradesWithoutNumbers;
  188. var avrage = sum/coursesWithRegularGrades;
  189.  
  190. return avrage;
  191. })();
  192.  
  193. var WeightedAverage = (function(){
  194. var pointsSum = 0;
  195. var pointsTimesGradeSum =0;
  196. selectedRows.each(function(){
  197. var grade = Number($(this).children().eq(4).text());
  198. var points = Number($(this).children().eq(3).text());
  199. if( !isNaN(grade)){
  200. pointsSum += points;
  201. pointsTimesGradeSum += points*grade;
  202. }
  203. });
  204. return pointsTimesGradeSum/pointsSum;
  205. })();
  206.  
  207.  
  208. return {
  209. WeightedAverage: WeightedAverage,
  210. average: avrage
  211. }
  212. }
  213.  
  214.  
  215. (function plusMinus(){
  216.  
  217. $('.plus').click(function(e){
  218. e.stopPropagation();
  219. var gradeElement =$(this).prev(".grade");
  220. var grade = Number(gradeElement.text());
  221. // If is not undefined
  222. if (!isNaN(grade)) {
  223. // Increment
  224. $(gradeElement).text(boundValue(grade+1));
  225. } else {
  226. // Otherwise put a 0 there
  227. $(gradeElement).text(0);
  228. }
  229. });
  230.  
  231. $('.minus').click(function(e){
  232. e.stopPropagation();
  233. var gradeElement = $(this).prevAll(".grade");
  234. var grade = Number(gradeElement.text());
  235. // If is not undefined
  236. if (!isNaN(grade)) {
  237. // Increment
  238. $(gradeElement).text(boundValue(grade-1));
  239. } else {
  240. // Otherwise put a 0 there
  241. $(gradeElement).text(0);
  242. }
  243. });
  244.  
  245. var boundValue = function(value){
  246. if(value > 5)return 5;
  247. if(value < 3)return 3;
  248. return value;
  249. }
  250.  
  251. })();
  252.  
  253.  
  254.  
  255.