diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..11586a5 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,22 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/javascript-node +{ + "name": "Node.js", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/javascript-node:1-18-bookworm", + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "npm install" + + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..8214165 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,27 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [4.0.0] - 2023-10-16 + +### Added + +- Settings caching to display the average faster. +- Dev container for contributors. + +### Fixed +- NaN average if the only assessments were non-numerical. + +### Changed + +- Settings UI. +- Many functions were rewritten from scratch. +- Readme file. + +### Removed + +- Console logs. +- Unused css styling. \ No newline at end of file diff --git a/README.md b/README.md index 514ac5a..08c5bd3 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,24 @@ -[![Chrome Web Store](https://img.shields.io/chrome-web-store/v/oggojknablgjgacijcjbioanonlkmfeg)](https://chrome.google.com/webstore/detail/librus-średnia/oggojknablgjgacijcjbioanonlkmfeg) -[![Chrome Web Store](https://img.shields.io/chrome-web-store/users/oggojknablgjgacijcjbioanonlkmfeg)](https://chrome.google.com/webstore/detail/librus-średnia/oggojknablgjgacijcjbioanonlkmfeg) -# ![Logo](assets/icon/32.png) Librus Średnia -Rozszerzenie do najpopularniejszych przeglądarek dodające możliwość wyświetlenia średniej z ocen, która nie zaśmieca strony. - -Wtyczka posiada ustawienia z możliwością konfigurowania każdej funkcji. +

Librus średnia

+ +

+ + Chrome web store + + + Users + + + Rating + +

+ +> Rozszerzenie do najpopularniejszych przeglądarek dodające możliwość wyświetlenia średniej z ocen, która nie zaśmieca strony. | Przed | Po | | ------------------------- | --------------------- | | ![przed](assets/img/before.png) | ![po](assets/img/after.png) | -# Funkcje w wersji 3.0.X +## ✨ Funkcje * Wyświetlanie średniej dla każdego przedmiotu w tabeli z ocenami. * Wyświetlanie średniej wszystkich ocen na dole tabeli. * Wyświetlanie średniej ocen śródrocznych i rocznych. @@ -20,32 +29,34 @@ Wtyczka posiada ustawienia z możliwością konfigurowania każdej funkcji. * Synchronizowanie ustawień między przeglądarkami, gdy użytkownik jest do niej zalogowany (jeśli przeglądarka wspiera synchronizację). * Automatyczne przełączanie planu lekcji na najbliższy tydzień w weekend po otwarciu go. -# Sposób liczenia średniej +**Wtyczka posiada ustawienia z możliwością konfigurowania każdej funkcji.** + +## 🧮 Sposób liczenia średniej Do średniej domyślnie liczą się tylko oceny oznaczone `Licz do średniej: tak`. Pod uwagę jest brana waga. Domyślnie `+` dodaje 0.5 do wartości oceny, a `-` odejmuje 0.25. Oceny niezawierające *normalnej* liczby nie są brane pod uwagę. Parametry liczenia można zmienić w ustawieniach wtyczki (wciskając ikonkę wtyczki). -# Zgłaszanie błędów -Wejdź w zakładkę `Issues` i utwórz nowy wątek. - -# Instalacja +## 🚀 Instalacja -## [Chrome](https://chrome.google.com/webstore/detail/librus-średnia/oggojknablgjgacijcjbioanonlkmfeg) +### [Chrome](https://chrome.google.com/webstore/detail/librus-średnia/oggojknablgjgacijcjbioanonlkmfeg) -## [Opera (Przez chrome web store)](https://chrome.google.com/webstore/detail/librus-średnia/oggojknablgjgacijcjbioanonlkmfeg) +### [Opera (Przez chrome web store)](https://chrome.google.com/webstore/detail/librus-średnia/oggojknablgjgacijcjbioanonlkmfeg) -## Firefox +### Firefox Wtyczka w firefoxie **obecnie nie działa**. -## Przeglądarki oparte na chrominium +### Przeglądarki oparte na chrominium Jeśli się da to przez [chrome web store](https://chrome.google.com/webstore/detail/librus-średnia/oggojknablgjgacijcjbioanonlkmfeg) ### Instalacja ręczna 1. Sklonuj repozytorium. -2. Uruchom w konsoli polecenie `npm install` (wymagane Node.js v18 i npm (testowane na 9.8)). +2. Uruchom w konsoli polecenie `npm install` (wymagane Node.js v18 i npm (testowane na 9.8)). Można użyć `dev container`. 3. Uruchom w konsoli polecenie `npm run dev`. 4. W Twojej przeglądarce wejdź w Rozszerzenia -> Zarządzaj rozszerzeniami. 5. Włącz tryb dewelopera. 6. Wciśnij "Załaduj rozpakowane" i wybierz folder `extensions/combined/dist/chrome`, gdzie znajduje się rozpakowana wtyczka. -# Mogę wesprzeć projekt? +## ❗Zgłaszanie błędów +Wejdź w zakładkę `Issues` i utwórz nowy wątek. + +## 🤝 Mogę wesprzeć projekt? Tak. Możesz pomóc go rozwijać lub możesz wesprzeć projekt finansowo. Zerknij na link po prawej stronie pod napisem `Sponsor this project`. \ No newline at end of file diff --git a/extensions/combined/background.js b/extensions/combined/background.js index 7121f9b..2698851 100644 --- a/extensions/combined/background.js +++ b/extensions/combined/background.js @@ -1,21 +1,2 @@ -const filter = { - url: [ - { - urlMatches: "https://synergia.librus.pl/przegladaj_plan_lekcji" - }, - { - urlMatches: "http://synergia.librus.pl/przegladaj_plan_lekcji" - }, - ], -}; - -chrome.webNavigation.onCreatedNavigationTarget.addListener(async (details) => { - let nextWeekAtWeekend; - await chrome.storage.sync.get(["nextWeekAtWeekend"]).then((result) => {nextWeekAtWeekend = result.nextWeekAtWeekend ?? true}); - if (!nextWeekAtWeekend) return; - chrome.scripting.executeScript({ - target: { tabId: details.tabId }, - files: ["przegladaj_plan_lekcji.inject-script.js"], - world: "MAIN" - }); -}, filter); \ No newline at end of file +import "./src/background/messageHandler" +import "./src/background/przegladaj_plan_lekcji_injector" \ No newline at end of file diff --git a/extensions/combined/manifest-chrome.json b/extensions/combined/manifest-chrome.json index d4f7d16..ac7b8d6 100644 --- a/extensions/combined/manifest-chrome.json +++ b/extensions/combined/manifest-chrome.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Librus Średnia", - "version": "3.0.0", + "version": "4.0.0", "description": "Wtyczka wyświetlająca średnią ocen dla każdego przedmiotu, mimo że ta funkcja została wyłączona przez administratora szkoły.", "author": "Krzysztof Kwiatkowski", "icons": { diff --git a/extensions/combined/src/background/messageHandler.js b/extensions/combined/src/background/messageHandler.js new file mode 100644 index 0000000..1c841c4 --- /dev/null +++ b/extensions/combined/src/background/messageHandler.js @@ -0,0 +1,14 @@ +"use strict"; +import storage from "./Storage"; + +chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { + if (request.message == "saveSettings") { + storage.save(request.body); + } + else if (request.message == "getSetting") { + (async () => { + sendResponse(await storage.get(request.key)); + })(); + return true; + } +}) \ No newline at end of file diff --git a/extensions/combined/src/background/przegladaj_plan_lekcji_injector.js b/extensions/combined/src/background/przegladaj_plan_lekcji_injector.js new file mode 100644 index 0000000..647817c --- /dev/null +++ b/extensions/combined/src/background/przegladaj_plan_lekcji_injector.js @@ -0,0 +1,20 @@ +"use strict"; +import storage from "./Storage"; + +const filter = { + url: [ + { + hostSuffix: "synergia.librus.pl", + pathPrefix: "/przegladaj_plan_lekcji" + } + ], +}; + +chrome.webNavigation.onCreatedNavigationTarget.addListener(async (details) => { + if (!await storage.get("nextWeekAtWeekend")) return; + chrome.scripting.executeScript({ + target: { tabId: details.tabId }, + files: ["przegladaj_plan_lekcji.inject-script.js"], + world: "MAIN" + }); +}, filter); \ No newline at end of file diff --git a/extensions/combined/src/background/storage.js b/extensions/combined/src/background/storage.js new file mode 100644 index 0000000..621efa6 --- /dev/null +++ b/extensions/combined/src/background/storage.js @@ -0,0 +1,56 @@ +"use strict"; +// https://stackoverflow.com/questions/1479319/simplest-cleanest-way-to-implement-a-singleton-in-javascript +let storage = (function () { + // Private methods + const corrrectSettingsObject = { + plus: 0.5, + minus: 0.25, + tylkoLiczDoSredniej: true, + schowajZachowanie: true, + ignoreCorrectedGrades: true, + nextWeekAtWeekend: true + }; + const correctSettingsObjectLength = Object.keys(corrrectSettingsObject).length; + + let cache = {}; + + function checkSettingsObject(settingsObject) { + let settingsObjectLength = Object.keys(settingsObject).length; + if (settingsObjectLength != correctSettingsObjectLength) { + throw new Error(`Settings object length is ${settingsObjectLength}. Expected ${correctSettingsObjectLength}`) + } + + Object.keys(corrrectSettingsObject).forEach((property) => { + if (!settingsObject.hasOwnProperty(property)) { + throw new Error(`Settings object has no ${property} property.`) + }; + }) + + return true; + } + + // Public methods + return { + save: function (settingsObject) { + if (checkSettingsObject(settingsObject)) { + chrome.storage.sync.set(settingsObject); + cache = settingsObject; + } else { + throw new Error("Incorrect settings object"); + } + }, + + get: async function (key) { + if (cache[key]) { + return cache[key]; + } else { + await chrome.storage.sync.get([key]).then((result) => {cache[key] = result[key] ?? corrrectSettingsObject[key] }); + return cache[key]; + } + } + } +}) + +Object.freeze(storage); + +module.exports = storage(); \ No newline at end of file diff --git a/extensions/combined/src/popup/popup.css b/extensions/combined/src/popup/popup.css new file mode 100644 index 0000000..abbd093 --- /dev/null +++ b/extensions/combined/src/popup/popup.css @@ -0,0 +1,67 @@ +body { + background-color: #282922; + color: white; + width: 300px; +} + +table { + border-collapse: collapse; + font-size: 12px; +} + +tr { + border-bottom: 1px #a4c800 solid; +} + +tr:last-child { + border-bottom: none !important; +} + +tr:hover { + background-color: #303030; +} + +tr:last-child:hover { + background-color: #282922 !important; +} + +input[type=number], input[type=submit] { + background-color: #303030; + color: white; + border-radius: 5px; + border: 1px #a4c800 solid; + width: 50px; +} + +input[type=submit]:hover { + background-color: #a4c800; +} + +input[type=submit] { + margin-top: 5px; + padding: 0px; + height: 25px; + cursor: pointer; +} + +input[type=checkbox] { + height: 25px; + width: 25px; + cursor: pointer; +} + +/* unvisited and visited link */ +a:link, a:visited { + color: #a4c800; +} + +a:hover, a:active { + color: #e2fb72; +} + +footer { + display: flex; + justify-content: space-around; + align-items: center; + margin-top: 10px; +} \ No newline at end of file diff --git a/extensions/combined/src/popup/popup.html b/extensions/combined/src/popup/popup.html index ad5081d..efe0a35 100644 --- a/extensions/combined/src/popup/popup.html +++ b/extensions/combined/src/popup/popup.html @@ -3,93 +3,50 @@ - +

Ustawienia

-
- -

- -

- -

- -

- -

- -

- -
- Po zapisaniu ustawień odśwież stronę -
-
- GitHub -
-
- tipply -
-
- Docent Company + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/extensions/combined/src/popup/popup.js b/extensions/combined/src/popup/popup.js index de39091..b235a52 100644 --- a/extensions/combined/src/popup/popup.js +++ b/extensions/combined/src/popup/popup.js @@ -1,37 +1,52 @@ -document.addEventListener("DOMContentLoaded", async function() { - var plusInput = document.getElementById("plus"); - let minusInput = document.getElementById("minus"); - let tylkoLiczDoSredniej = document.getElementById("tylkoLiczDoSredniej"); - let schowajZachowanie = document.getElementById("schowajZachowanie"); - let ignoreCorrectedGrades = document.getElementById("ignoreCorrectedGrades"); - let nextWeekAtWeekend = document.getElementById("nextWeekAtWeekend"); - let submitButton = document.getElementById("submit"); +"use strict"; +document.addEventListener("DOMContentLoaded", async function () { + const $ = document.querySelector.bind(document); - chrome.storage.sync.get(["plus"]).then((result) => {plusInput.value = result.plus ?? 0.5}); - chrome.storage.sync.get(["minus"]).then((result) => {minusInput.value = result.minus ?? 0.25}); - chrome.storage.sync.get(["tylkoLiczDoSredniej"]).then((result) => {tylkoLiczDoSredniej.checked = result.tylkoLiczDoSredniej ?? true}); - chrome.storage.sync.get(["schowajZachowanie"]).then((result) => {schowajZachowanie.checked = result.schowajZachowanie ?? true}); - chrome.storage.sync.get(["ignoreCorrectedGrades"]).then((result) => {ignoreCorrectedGrades.checked = result.ignoreCorrectedGrades ?? true}); - chrome.storage.sync.get(["nextWeekAtWeekend"]).then((result) => {nextWeekAtWeekend.checked = result.nextWeekAtWeekend ?? true}); - submitButton.addEventListener("click", onClickEvent); + const plusInput = $("#plus"); + const minusInput = $("#minus"); + const tylkoLiczDoSredniej = $("#tylkoLiczDoSredniej"); + const schowajZachowanie = $("#schowajZachowanie"); + const ignoreCorrectedGrades = $("#ignoreCorrectedGrades"); + const nextWeekAtWeekend = $("#nextWeekAtWeekend"); + const submitButton = $("#submit"); + plusInput.value = await getData("plus"); + minusInput.value = await getData("minus"); + tylkoLiczDoSredniej.checked = await getData("tylkoLiczDoSredniej"); + schowajZachowanie.checked = await getData("schowajZachowanie"); + ignoreCorrectedGrades.checked = await getData("ignoreCorrectedGrades"); + nextWeekAtWeekend.checked = await getData("nextWeekAtWeekend"); - function onClickEvent() { + submitButton.addEventListener("click", () => { saveData(plusInput.value, minusInput.value, tylkoLiczDoSredniej.checked, schowajZachowanie.checked, ignoreCorrectedGrades.checked, nextWeekAtWeekend.checked); - }; + reloadLibrusTab(); + }); }); function saveData(plusValue, minusValue, tylkoLiczDoSredniejValue, schowajZachowanieValue, ignoreCorrectedGradesValue, nextWeekAtWeekendValue) { plusValue = parseFloat(plusValue); minusValue = parseFloat(minusValue); - chrome.storage.sync.set( - { + chrome.runtime.sendMessage({ + "message": "saveSettings", "body": { plus: plusValue, minus: minusValue, tylkoLiczDoSredniej: tylkoLiczDoSredniejValue, schowajZachowanie: schowajZachowanieValue, ignoreCorrectedGrades: ignoreCorrectedGradesValue, nextWeekAtWeekend: nextWeekAtWeekendValue + } + }); +}; + +async function getData(key) { + return await chrome.runtime.sendMessage({ "message": "getSetting", "key": key }); +} + +function reloadLibrusTab() { + chrome.tabs.query({ url: ["*://synergia.librus.pl/*"] }, function (tabs) { + tabs.forEach(element => { + chrome.tabs.reload(element.id); }); -}; \ No newline at end of file + }); +} \ No newline at end of file diff --git a/extensions/combined/src/przegladaj_oceny/Grade.js b/extensions/combined/src/przegladaj_oceny/Grade.js index 79a9a30..5d761af 100644 --- a/extensions/combined/src/przegladaj_oceny/Grade.js +++ b/extensions/combined/src/przegladaj_oceny/Grade.js @@ -1,3 +1,4 @@ +"use strict"; class Grade { constructor(value, weight, countToAverage) { this.value = value; @@ -8,7 +9,7 @@ class Grade { function parseGradeFromHtmlObject(html, plusValue, minusValue, tylkoLiczDoSredniej) { function parseWeight(text) { - weight = parseInt(text[6]); + const weight = parseInt(text[6]); if (isNaN(weight)) return 1; return weight; }; @@ -19,19 +20,21 @@ function parseGradeFromHtmlObject(html, plusValue, minusValue, tylkoLiczDoSredni }; function parseValue(text, plusValue, minusValue) { - value = parseInt(text); + let value = parseInt(text[0]); if (isNaN(value)) return text; - if (text[1] == '+') value += plusValue; // grade with '+' - else if (text[1] == '-') value -= minusValue; // grade with '-' + if (text.length == 2) { + if (text[1] == '+') value += plusValue; // grade with '+' + else if (text[1] == '-') value -= minusValue; // grade with '-' + } return value; }; - title = html.getAttribute("title"); - titleArray = title.split("
"); + const title = html.getAttribute("title"); + const titleArray = title.split("
"); - value = parseValue(html.innerText, plusValue, minusValue); - weight = 1; - countToAverage = false; + const value = parseValue(html.innerText, plusValue, minusValue); + let weight = 1; + let countToAverage = false; for (const text of titleArray) { if (text.includes("Waga: ")) weight = parseWeight(text); else if (text.includes("Licz do średniej:")) countToAverage = parseCountToAverage(text, tylkoLiczDoSredniej); @@ -41,13 +44,15 @@ function parseGradeFromHtmlObject(html, plusValue, minusValue, tylkoLiczDoSredni function gradesTdToList(gradesTd, plusValue, minusValue, tylkoLiczDoSredniej, ignoreCorrectedGrades) { - list = []; + let list = []; - let grades = gradesTd.children; + const grades = gradesTd.children; for (const gradeGroup of grades) { const gradesInGradeGroup = gradeGroup.children; if (gradesInGradeGroup[0].tagName == "SPAN") { - if (ignoreCorrectedGrades) list.push(parseGradeFromHtmlObject(gradesInGradeGroup[gradesInGradeGroup.length-1].getElementsByTagName("a")[0])); + if (ignoreCorrectedGrades) { + list.push(parseGradeFromHtmlObject(gradesInGradeGroup[gradesInGradeGroup.length-1].getElementsByTagName("a")[0], plusValue, minusValue, tylkoLiczDoSredniej)); + } else { for (const grade of gradesInGradeGroup) { list.push(parseGradeFromHtmlObject(grade.getElementsByTagName("a")[0], plusValue, minusValue, tylkoLiczDoSredniej)); diff --git a/extensions/combined/src/przegladaj_oceny/Subject.js b/extensions/combined/src/przegladaj_oceny/Subject.js index f7e7644..c962bd4 100644 --- a/extensions/combined/src/przegladaj_oceny/Subject.js +++ b/extensions/combined/src/przegladaj_oceny/Subject.js @@ -1,9 +1,34 @@ -class Subject { +import { average } from "../../utils"; + +export class Subject { constructor(name, gradesFirstList, gradesSecondList) { this.name = name; - this.gradesFirst = gradesFirstList; - this.gradesSecond = gradesSecondList; + this._gradesFirst = gradesFirstList; + this._gradesSecond = gradesSecondList; + this.updateAverage(); }; -}; -module.exports = Subject; \ No newline at end of file + get gradesFirst() { + return this._gradesFirst; + } + + set gradesFirst(grades) { + this._gradesFirst = grades; + updateAverage(); + } + + get gradesSecond() { + return this._gradesSecond; + } + + set gradesSecond(grades) { + this._gradesSecond = grades; + updateAverage(); + } + + updateAverage() { + this.averageFirstTerm = average(this.gradesFirst); + this.averageSecondTerm = average(this.gradesSecond); + this.averageYear = average(this.gradesFirst.concat(this.gradesSecond)); + } +}; \ No newline at end of file diff --git a/extensions/combined/src/przegladaj_oceny/collapse_zachowanie.js b/extensions/combined/src/przegladaj_oceny/collapse_zachowanie.js index e67b60b..342bd4d 100644 --- a/extensions/combined/src/przegladaj_oceny/collapse_zachowanie.js +++ b/extensions/combined/src/przegladaj_oceny/collapse_zachowanie.js @@ -1,6 +1,6 @@ +"use strict"; async function main() { - let schowajZachowanie; - await chrome.storage.sync.get(["schowajZachowanie"]).then((result) => {schowajZachowanie = result.schowajZachowanie ?? true}); + const schowajZachowanie = await chrome.runtime.sendMessage({ "message": "getSetting", "key": "schowajZachowanie" }); if (schowajZachowanie) document.getElementById("przedmioty_zachowanie_node").click(); }; diff --git a/extensions/combined/src/przegladaj_oceny/generateTdsIndexes.js b/extensions/combined/src/przegladaj_oceny/generateTdsIndexes.js index e2ad752..8f8ae2e 100644 --- a/extensions/combined/src/przegladaj_oceny/generateTdsIndexes.js +++ b/extensions/combined/src/przegladaj_oceny/generateTdsIndexes.js @@ -1,40 +1,38 @@ "use strict"; -const Utils = require("../../utils"); +import {getTopLevelChildByTagName} from "../../utils" var wasGrades = false; function grades() { if (wasGrades) return "gradesSecondTerm"; wasGrades = true; return "gradesFirstTerm"; -} -const mapColumnHeadersToTdsIndexes = { - "Oceny bieżące": grades, - "Śr.I": "averageFirstTerm", - "(I)": "annualFirstPredirect", - "I": "annualFirst", - "Śr.II": "averageSecondTerm", - "(II)": "annualSecondPredirect", - "II": "annualSecond", - "Śr.R": "averageYear", - "(R)": "annualYearPredirect", - "R": "annualYear" } +const mapColumnHeadersToTdsIndexes = new Map([ + ["Oceny bieżące", grades], + ["Śr.I", "averageFirstTerm"], + ["(I)", "annualFirstPredirect"], + ["I", "annualFirst"], + ["Śr.II", "averageSecondTerm"], + ["(II)", "annualSecondPredirect"], + ["II", "annualSecond"], + ["Śr.R", "averageYear"], + ["(R)", "annualYearPredirect"], + ["R", "annualYear"] +]) + export function generateTdsIndexes(table) { - let tdsIndexes = {"subjectName": 1}; + let tdsIndexes = new Map([["subjectName", 1]]); - let tableHead = Utils.getTopLevelChildByTagName(table, "thead"); - let rowWithDescriptions = tableHead.children[1]; // Second row with column descriptions: "oceny bieżące", "Śr. I" etc. + const tableHead = getTopLevelChildByTagName(table, "thead"); + const rowWithDescriptions = tableHead.children[1]; // Second row with column descriptions: "oceny bieżące", "Śr. I" etc. let array = Array.from(rowWithDescriptions.children); let counter = 2; for (const column of array) { - let mappedKey = mapColumnHeadersToTdsIndexes[column.innerText]; - if (typeof mappedKey === "function") { - tdsIndexes[mappedKey()] = counter; - } else { - tdsIndexes[mappedKey] = counter; - } + const mappedKey = mapColumnHeadersToTdsIndexes.get(column.innerText); + const key = typeof mappedKey === "function" ? mappedKey() : mappedKey; + tdsIndexes.set(key, counter); counter++; } diff --git a/extensions/combined/src/przegladaj_oceny/srednia.js b/extensions/combined/src/przegladaj_oceny/srednia.js index a75d61d..0e1389e 100644 --- a/extensions/combined/src/przegladaj_oceny/srednia.js +++ b/extensions/combined/src/przegladaj_oceny/srednia.js @@ -1,25 +1,10 @@ "use strict"; const Grade = require("./Grade"); -const Subject = require("./Subject"); -const Utils = require("../../utils"); -const GenerateTdsIndexes = require("./generateTdsIndexes"); - -var tdsIndexes; - -function average(gradesList) { - let sum = 0; - let counter = 0; - if (gradesList.length == 0) return (0).toFixed(2); - for (const grade of gradesList) { - if (grade.countToAverage && !isNaN(grade.value)) { - sum += (grade.value * grade.weight); - counter += grade.weight; - } - } - return (sum/counter).toFixed(2); -}; +import {Subject} from "./Subject"; +import { getTopLevelChildByTagName, average } from "../../utils"; +import { generateTdsIndexes } from "./generateTdsIndexes"; -function generateFooter(tfoot, subjects, annuals) { +function generateFooter(tfoot, tdsIndexes, subjects, annuals) { function generateTd(innerText, title) { let td = document.createElement("td"); td.setAttribute("colspan", 1); @@ -27,156 +12,141 @@ function generateFooter(tfoot, subjects, annuals) { td.innerText = innerText || null; tr.appendChild(td); } - var tr = Utils.getTopLevelChildByTagName(tfoot, "tr"); - Utils.getTopLevelChildByTagName(tr, "td").remove(); + let tr = getTopLevelChildByTagName(tfoot, "tr"); + getTopLevelChildByTagName(tr, "td").remove(); const {gradesFirst, gradesSecond} = Grade.gradesFromSubjects(subjects); generateTd(); // Spacing generateTd("Średnie", "Średnie wyliczone dzięki wtyczce Librus Średnia wykonanej przez https://docentcompany.com"); - if (tdsIndexes.hasOwnProperty("gradesFirstTerm")) generateTd(); - if (tdsIndexes.hasOwnProperty("averageFirstTerm")) generateTd(average(gradesFirst), "Średnia ocen z pierwszego semestu ze wszystkich przedmiotów."); - if (tdsIndexes.hasOwnProperty("annualFirstPredirect")) generateTd(annuals["annualFirstPredirect"], "Średnia ocen przewidywanych na pierwszy semestr."); - if (tdsIndexes.hasOwnProperty("annualFirst")) generateTd(annuals["annualFirst"], "Średnia ocen śródrocznych na pierwszy semestr."); + if (tdsIndexes.get("gradesFirstTerm")) generateTd(); + if (tdsIndexes.get("averageFirstTerm")) generateTd(average(gradesFirst), "Średnia ocen z pierwszego semestu ze wszystkich przedmiotów."); + if (tdsIndexes.get("annualFirstPredirect")) generateTd(annuals["annualFirstPredirect"], "Średnia ocen przewidywanych na pierwszy semestr."); + if (tdsIndexes.get("annualFirst")) generateTd(annuals["annualFirst"], "Średnia ocen śródrocznych na pierwszy semestr."); - if (tdsIndexes.hasOwnProperty("gradesSecondTerm")) generateTd(); - if (tdsIndexes.hasOwnProperty("averageSecondTerm")) generateTd(average(gradesSecond), "Średnia ocen z drugiego semestu ze wszystkich przedmiotów."); - if (tdsIndexes.hasOwnProperty("annualSecondPredirect")) generateTd(annuals["annualSecondPredirect"], "Średnia ocen przewidywanych na drugi semestr."); - if (tdsIndexes.hasOwnProperty("annualSecond")) generateTd(annuals["annualSecond"], "Średnia ocen śródrocznych na drugi semestr."); + if (tdsIndexes.get("gradesSecondTerm")) generateTd(); + if (tdsIndexes.get("averageSecondTerm")) generateTd(average(gradesSecond), "Średnia ocen z drugiego semestu ze wszystkich przedmiotów."); + if (tdsIndexes.get("annualSecondPredirect")) generateTd(annuals["annualSecondPredirect"], "Średnia ocen przewidywanych na drugi semestr."); + if (tdsIndexes.get("annualSecond")) generateTd(annuals["annualSecond"], "Średnia ocen śródrocznych na drugi semestr."); - if (tdsIndexes.hasOwnProperty("averageYear")) generateTd(average(gradesFirst.concat(gradesSecond)), "Średnia ocen z pierwszego i drugiego semestu łącznie ze wszystkich przedmiotów."); - if (tdsIndexes.hasOwnProperty("annualYearPredirect")) generateTd(annuals["annualYearPredirect"], "Średnia ocen przewidywanych na koniec roku."); - if (tdsIndexes.hasOwnProperty("annualYear")) generateTd(annuals["annualYear"], "Średnia ocen rocznych."); + if (tdsIndexes.get("averageYear")) generateTd(average(gradesFirst.concat(gradesSecond)), "Średnia ocen z pierwszego i drugiego semestu łącznie ze wszystkich przedmiotów."); + if (tdsIndexes.get("annualYearPredirect")) generateTd(annuals["annualYearPredirect"], "Średnia ocen przewidywanych na koniec roku."); + if (tdsIndexes.get("annualYear")) generateTd(annuals["annualYear"], "Średnia ocen rocznych."); }; -function updateAverage(tds, subject) { - function updadeAverageForAnnual(tdsIndexKey, grades, title) { - if (!tdsIndexes.hasOwnProperty(tdsIndexKey)) return; - const td = tds[tdsIndexes[tdsIndexKey]]; - td.textContent = average(grades); +function updateAverage(tds, tdsIndexes, subject) { + function updadeAverageForAnnual(tdsIndexKey, average, title) { + if (!tdsIndexes.get(tdsIndexKey)) return; + let td = tds[tdsIndexes.get(tdsIndexKey)]; + td.textContent = average; td.setAttribute("title", title); td.setAttribute("class", "center"); } - updadeAverageForAnnual("averageFirstTerm", subject.gradesFirst, "Średnia ocen z pierwszego semestu z jednego przedmiotu."); - updadeAverageForAnnual("averageSecondTerm", subject.gradesSecond, "Średnia ocen z drugiego semestu z jednego przedmiotu."); - updadeAverageForAnnual("averageYear", subject.gradesFirst.concat(subject.gradesSecond), "Średnia ocen z pierwszego i drugiego semesteru łącznie z jednego przedmiotu."); + updadeAverageForAnnual("averageFirstTerm", subject.averageFirstTerm, "Średnia ocen z pierwszego semestu z jednego przedmiotu."); + updadeAverageForAnnual("averageSecondTerm", subject.averageSecondTerm, "Średnia ocen z drugiego semestu z jednego przedmiotu."); + updadeAverageForAnnual("averageYear", subject.averageYear, "Średnia ocen z pierwszego i drugiego semesteru łącznie z jednego przedmiotu."); }; -function generateSubjectListFromGradesTableBody(tbody, plusValue, minusValue, tylkoLiczDoSredniej, ignoreCorrectedGrades) { +function generateSubjectListFromGradesTableBody(tbody, tdsIndexes, plusValue, minusValue, tylkoLiczDoSredniej, ignoreCorrectedGrades) { let subjectList = []; for (const subject of tbody.children) { - if (subject.hasAttribute("name")) continue; - let tds = subject.getElementsByTagName("td"); - let subjectName = tds[tdsIndexes.subjectName].textContent; + if (subject.hasAttribute("name")) continue; // if it has name it is a table that can be expanded by clicking '+' icon. + const tds = subject.getElementsByTagName("td"); + const subjectName = tds[tdsIndexes.get("subjectName")].textContent; if (subjectName.includes("Zachowanie")) continue; - let gradesFirstList = Grade.gradesTdToList(tds[tdsIndexes.gradesFirstTerm], plusValue, minusValue, tylkoLiczDoSredniej, ignoreCorrectedGrades); - let gradesSecondList = Grade.gradesTdToList(tds[tdsIndexes.gradesSecondTerm], plusValue, minusValue, tylkoLiczDoSredniej, ignoreCorrectedGrades); - let subjectObject = new Subject(subjectName, gradesFirstList, gradesSecondList); + const gradesFirstList = Grade.gradesTdToList(tds[tdsIndexes.get("gradesFirstTerm")], plusValue, minusValue, tylkoLiczDoSredniej, ignoreCorrectedGrades); + const gradesSecondList = Grade.gradesTdToList(tds[tdsIndexes.get("gradesSecondTerm")], plusValue, minusValue, tylkoLiczDoSredniej, ignoreCorrectedGrades); + const subjectObject = new Subject(subjectName, gradesFirstList, gradesSecondList); - updateAverage(tds, subjectObject); + updateAverage(tds, tdsIndexes, subjectObject); subjectList.push(new Subject(subjectName, gradesFirstList, gradesSecondList)); }; return subjectList; }; -function annualAssements(tbody) { - let annuals = {}; +function annualAverages(tbody, tdsIndexes) { + let annualAverages = {}; + + let annualsTemp = { + // sum, counter (for average: sum/counter) + annualFirstPredirect: [0,0], + annualFirst: [0,0], + annualSecondPredirect: [0,0], + annualSecond: [0,0], + annualYearPredirect: [0,0], + annualYear: [0,0] + } - function parseAnnual(tds, tdsIndex) { + function getAnnualGrade(tds, tdsIndex) { let grade = tds[tdsIndex]; if (!grade) return null; - grade = Utils.getTopLevelChildByTagName(grade, "span"); + grade = getTopLevelChildByTagName(grade, "span"); if (!grade) return null; - grade = Utils.getTopLevelChildByTagName(grade, "a"); + grade = getTopLevelChildByTagName(grade, "a"); if (!grade || !grade.textContent) return null; return parseInt(grade.textContent); } - let annualFirstPredirectCounter = 0; - let annualFirstPredirectSum = 0; - let annualFirstCounter = 0; - let annualFirstSum = 0; - let annualSecondPredirectCounter = 0; - let annualSecondPredirectSum = 0; - let annualSecondCounter = 0; - let annualSecondSum = 0; - let annualYearPredirectCounter = 0; - let annualYearPredirectSum = 0; - let annualYearCounter = 0; - let annualYearSum = 0; + function parseAnnual(tds, annualAndTdsKey) { + const grade = getAnnualGrade(tds, tdsIndexes[annualAndTdsKey]); + if (grade) { + annualsTemp[annualAndTdsKey][0] += grade; + annualsTemp[annualAndTdsKey][1]++; + } + } + + function averageForAnnual(annualKey) { + const sum = annualsTemp[annualKey][0]; + const counter = annualsTemp[annualKey][1]; + if (counter == 0) return (0).toFixed(2); + return (sum / counter).toFixed(2); + } + + function saveAverageToAnnualAverages(annualKey) { + annualAverages[annualKey] = averageForAnnual(annualKey); + } + for (const subject of tbody.children) { if (subject.hasAttribute("name")) continue; - let tds = subject.getElementsByTagName("td"); - let subjectName = tds[tdsIndexes.subjectName].textContent; + const tds = subject.getElementsByTagName("td"); + const subjectName = tds[tdsIndexes.get("subjectName")].textContent; if (subjectName.includes("Zachowanie")) continue; - let annualFirstPredirectGrade = parseAnnual(tds, tdsIndexes.annualFirstPredirect); - let annualFirstGrade = parseAnnual(tds, tdsIndexes.annualFirst); - let annualSecondPredirectGrade = parseAnnual(tds, tdsIndexes.annualSecondPredirect); - let annualSecondGrade = parseAnnual(tds, tdsIndexes.annualSecond); - let annualYearPredirectGrade = parseAnnual(tds, tdsIndexes.annualYearPredirect); - let annualYearGrade = parseAnnual(tds, tdsIndexes.annualYear); - if (annualFirstPredirectGrade) { - annualFirstPredirectCounter++; - annualFirstPredirectSum += annualFirstPredirectGrade; - } - if (annualFirstGrade) { - annualFirstCounter++; - annualFirstSum += annualFirstGrade; - } - if (annualSecondPredirectGrade) { - annualSecondPredirectCounter++; - annualSecondPredirectSum += annualSecondPredirectGrade; - } - if (annualSecondGrade) { - annualSecondCounter++; - annualSecondSum += annualSecondGrade; - } - if (annualYearPredirectGrade) { - annualYearPredirectCounter++; - annualYearPredirectSum += annualYearPredirectGrade; - } - if (annualYearGrade) { - annualYearCounter++; - annualYearSum += annualYearGrade; - } + parseAnnual(tds, "annualFirstPredirect"); + parseAnnual(tds, "annualFirst"); + parseAnnual(tds, "annualSecondPredirect"); + parseAnnual(tds, "annualSecond"); + parseAnnual(tds, "annualYearPredirect"); + parseAnnual(tds, "annualYear"); } - annuals["annualFirstPredirect"] = (annualFirstPredirectSum / annualFirstPredirectCounter).toFixed(2); - annuals["annualFirst"] = (annualFirstSum / annualFirstCounter).toFixed(2); - annuals["annualSecondPredirect"] = (annualSecondPredirectSum / annualSecondPredirectCounter).toFixed(2); - annuals["annualSecond"] = (annualSecondSum / annualSecondCounter).toFixed(2); - annuals["annualYearPredirect"] = (annualYearPredirectSum / annualYearPredirectCounter).toFixed(2); - annuals["annualYear"] = (annualYearSum / annualYearCounter).toFixed(2); - - if (isNaN(annuals["annualFirstPredirect"])) annuals["annualFirstPredirect"] = (0).toFixed(2); - if (isNaN(annuals["annualFirst"])) annuals["annualFirst"] = (0).toFixed(2); - if (isNaN(annuals["annualSecond"])) annuals["annualSecond"] = (0).toFixed(2); - if (isNaN(annuals["annualYear"])) annuals["annualYear"] = (0).toFixed(2); - - return annuals; + + saveAverageToAnnualAverages("annualFirstPredirect"); + saveAverageToAnnualAverages("annualFirst"); + saveAverageToAnnualAverages("annualSecondPredirect"); + saveAverageToAnnualAverages("annualSecond"); + saveAverageToAnnualAverages("annualYearPredirect"); + saveAverageToAnnualAverages("annualYear"); + + return annualAverages; } async function main() { - let table = document.getElementsByClassName("decorated stretch")[1]; - let tbody = Utils.getTopLevelChildByTagName(table, "tbody"); - - tdsIndexes = GenerateTdsIndexes.generateTdsIndexes(table); - - let plusValue; - let minusValue; - let tylkoLiczDoSredniej; - let ignoreCorrectedGrades; - - await chrome.storage.sync.get(["plus"]).then((result) => {plusValue = result.plus ?? 0.5}); - await chrome.storage.sync.get(["minus"]).then((result) => {minusValue = result.minus ?? 0.25}); - await chrome.storage.sync.get(["tylkoLiczDoSredniej"]).then((result) => {tylkoLiczDoSredniej = result.tylkoLiczDoSredniej ?? true}); - await chrome.storage.sync.get(["ignoreCorrectedGrades"]).then((result) => {ignoreCorrectedGrades = result.ignoreCorrectedGrades ?? true}) - let subjectList = await generateSubjectListFromGradesTableBody(tbody, plusValue, minusValue, tylkoLiczDoSredniej, ignoreCorrectedGrades); - let annuals = annualAssements(tbody); - generateFooter(Utils.getTopLevelChildByTagName(table, "tfoot"), subjectList, annuals); + const table = document.getElementsByClassName("decorated stretch")[1]; + const tbody = getTopLevelChildByTagName(table, "tbody"); + + const tdsIndexes = generateTdsIndexes(table); + + const plusValue = await chrome.runtime.sendMessage({ "message": "getSetting", "key": "plus" }); + const minusValue = await chrome.runtime.sendMessage({ "message": "getSetting", "key": "minus" }); + const tylkoLiczDoSredniej = await chrome.runtime.sendMessage({ "message": "getSetting", "key": "tylkoLiczDoSredniej" }); + const ignoreCorrectedGrades = await chrome.runtime.sendMessage({ "message": "getSetting", "key": "ignoreCorrectedGrades" }); + + let subjectList = generateSubjectListFromGradesTableBody(tbody, tdsIndexes, plusValue, minusValue, tylkoLiczDoSredniej, ignoreCorrectedGrades); + let annuals = annualAverages(tbody, tdsIndexes); + generateFooter(getTopLevelChildByTagName(table, "tfoot"), tdsIndexes, subjectList, annuals); }; main(); \ No newline at end of file diff --git a/extensions/combined/src/przegladaj_plan_lekcji/nextWeekAtWeekend.js b/extensions/combined/src/przegladaj_plan_lekcji/nextWeekAtWeekend.js index 062cfd4..9ccfef6 100644 --- a/extensions/combined/src/przegladaj_plan_lekcji/nextWeekAtWeekend.js +++ b/extensions/combined/src/przegladaj_plan_lekcji/nextWeekAtWeekend.js @@ -1,20 +1,17 @@ function main() { - let planLekcji = document.getElementsByClassName("plan-lekcji")[0]; - console.log(planLekcji) - let headers = planLekcji.getElementsByTagName("thead")[0].getElementsByTagName("tr")[0]; + const timetable = document.getElementsByClassName("plan-lekcji")[0]; + const headers = timetable.getElementsByTagName("thead")[0].getElementsByTagName("tr")[0]; - let saturdayString = headers.childNodes[headers.childNodes.length-3].lastChild.textContent; - let saturday = new Date(saturdayString).setHours(0,0,0,0); + const saturdayString = headers.childNodes[headers.childNodes.length-3].lastChild.textContent; + const saturday = new Date(saturdayString).setHours(0,0,0,0); - let sundayString = headers.childNodes[headers.childNodes.length-2].lastChild.textContent; - let sunday = new Date(sundayString).setHours(0,0,0,0); + const sundayString = headers.childNodes[headers.childNodes.length-2].lastChild.textContent; + const sunday = new Date(sundayString).setHours(0,0,0,0); - let today = new Date().setHours(0,0,0,0); + const today = new Date().setHours(0,0,0,0); if (today == saturday || today == sunday) { zmienTydzien(1); // function from original librus site } } -document.addEventListener("DOMContentLoaded", main); - -// main(); \ No newline at end of file +document.addEventListener("DOMContentLoaded", main); \ No newline at end of file diff --git a/extensions/combined/utils.js b/extensions/combined/utils.js index c12524b..547bdab 100644 --- a/extensions/combined/utils.js +++ b/extensions/combined/utils.js @@ -8,4 +8,18 @@ function getTopLevelChildByTagName(element, tagName) { return null; }; -module.exports = {getTopLevelChildByTagName}; \ No newline at end of file +function average(gradesList) { + let sum = 0; + let counter = 0; + if (gradesList.length == 0) return (0).toFixed(2); + for (const grade of gradesList) { + if (grade.countToAverage && !isNaN(grade.value)) { + sum += (grade.value * grade.weight); + counter += grade.weight; + } + } + if (counter == 0) return (0).toFixed(2); + return (sum/counter).toFixed(2); +}; + +module.exports = {getTopLevelChildByTagName, average}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 6924490..7fd8a15 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "librus-srednia", - "version": "2.0.0", + "version": "3.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "librus-srednia", - "version": "2.0.0", + "version": "3.0.0", "license": "ISC", "devDependencies": { "copy-webpack-plugin": "^11.0.0", diff --git a/package.json b/package.json index badbf40..eb39297 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "librus-srednia", - "version": "3.0.0", + "version": "4.0.0", "description": "Rozszerzenie do najpopularniejszych przeglądarek dodające możliwość wyświetlenia średniej z ocen, która nie zaśmieca strony.", "main": "index.js", "scripts": {