From 8c57152fe4dc85443edf8525c8785707a8000b54 Mon Sep 17 00:00:00 2001
From: Zan <62830223+Zan1456@users.noreply.github.com>
Date: Mon, 15 Sep 2025 22:17:50 +0200
Subject: [PATCH] Use localstorage rather than cookies
---
absences/absences.js | 8 +-
dashboard/dashboard.js | 21 +++--
global/language.js | 36 ++++----
global/navigation.js | 16 ++--
global/theme.js | 59 +++++++-----
grades/grades.js | 32 +++----
homework/homework.js | 22 ++---
logout/logout.js | 6 +-
manifest.json | 12 ++-
roleselect/roleselect.js | 8 +-
search/search.js | 4 +-
timetable/timetable.js | 75 ++++++++-------
tools/background.js | 106 +++++++++++++++++++++
tools/cookieManager.js | 25 -----
tools/createTemplate.js | 9 +-
tools/storageManager.js | 193 +++++++++++++++++++++++++++++++++++++++
16 files changed, 470 insertions(+), 162 deletions(-)
create mode 100644 tools/background.js
delete mode 100644 tools/cookieManager.js
create mode 100644 tools/storageManager.js
diff --git a/absences/absences.js b/absences/absences.js
index de4e023..0729a96 100644
--- a/absences/absences.js
+++ b/absences/absences.js
@@ -1,11 +1,11 @@
async function collectAbsencesData() {
const basicData = {
schoolInfo: {
- name: cookieManager.get("schoolName") || "Iskola",
- id: cookieManager.get("schoolCode") || "",
+ name: await storageManager.get("schoolName", "OM azonosító - Iskola neve"),
+ id: await storageManager.get("schoolCode", ""),
},
userData: {
- name: cookieManager.get("userName") || "Felhasználó",
+ name: await storageManager.get("userName", "Felhasználónév"),
time:
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
"45:00",
@@ -281,7 +281,7 @@ async function transformAbsencesPage() {
container.className = 'kreta-container';
const headerDiv = document.createElement('div');
const parser = new DOMParser();
- const doc = parser.parseFromString(createTemplate.header(), 'text/html');
+ const doc = parser.parseFromString(await createTemplate.header(), 'text/html');
const tempDiv = doc.body;
while (tempDiv.firstChild) {
headerDiv.appendChild(tempDiv.firstChild);
diff --git a/dashboard/dashboard.js b/dashboard/dashboard.js
index 2c74233..fdedd2f 100644
--- a/dashboard/dashboard.js
+++ b/dashboard/dashboard.js
@@ -292,18 +292,22 @@ class DashboardDataManager {
class DashboardRenderer {
constructor(data) {
+ this.baseData = data;
+ }
+
+ async init() {
this.data = {
- ...data,
+ ...this.baseData,
schoolInfo: {
name:
- cookieManager.get(COOKIE_KEYS.SCHOOL_NAME) || DEFAULT_VALUES.SCHOOL,
- id: cookieManager.get(COOKIE_KEYS.SCHOOL_CODE) || "",
+ await storageManager.get("schoolName", "OM azonosító - Iskola neve"),
+ id: await storageManager.get("schoolCode", ""),
},
userData: {
- name: cookieManager.get(COOKIE_KEYS.USER_NAME) || DEFAULT_VALUES.USER,
+ name: await storageManager.get("userName", "Felhasználónév"),
time:
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
- DEFAULT_VALUES.TIMER,
+ "45:00",
},
};
this.schoolNameFull = `${this.data.schoolInfo.id} - ${this.data.schoolInfo.name}`;
@@ -475,14 +479,15 @@ class DashboardRenderer {
`;
}
- render() {
+ async render() {
+ await this.init();
document.body.innerHTML = '';
const kretaContainer = document.createElement('div');
kretaContainer.className = 'kreta-container';
const headerDiv = document.createElement('div');
const parser = new DOMParser();
- const headerDoc = parser.parseFromString(createTemplate.header(), 'text/html');
+ const headerDoc = parser.parseFromString(await createTemplate.header(), 'text/html');
const headerContent = headerDoc.body;
while (headerContent.firstChild) {
headerDiv.appendChild(headerContent.firstChild);
@@ -573,7 +578,7 @@ class DashboardApplication {
const dashboardData = await dataManager.extractAllData();
const renderer = new DashboardRenderer(dashboardData);
- renderer.render();
+ await renderer.render();
} catch (error) {
console.error("Error initializing dashboard:", error);
}
diff --git a/global/language.js b/global/language.js
index 9441a9d..420a155 100644
--- a/global/language.js
+++ b/global/language.js
@@ -6,7 +6,8 @@
try {
currentLanguage = language;
- cookieManager.set("languagePreference", language);
+ await storageManager.set("languagePreference", language);
+
localStorage.setItem("languagePreference", language);
await loadTranslations(language);
@@ -82,20 +83,25 @@
}
async function initializeLanguage() {
- const cookieLanguage = cookieManager.get("languagePreference");
- const localStorageLanguage = localStorage.getItem("languagePreference");
+ try {
+ const storageLanguage = await storageManager.get("languagePreference");
+ const localStorageLanguage = localStorage.getItem("languagePreference");
+ const language = storageLanguage || localStorageLanguage || "hu";
- const language = cookieLanguage || localStorageLanguage || "hu";
+ await setLanguage(language);
+ loadTranslationsForPage();
- await setLanguage(language);
- loadTranslationsForPage();
-
- if (cookieLanguage !== localStorageLanguage) {
- if (cookieLanguage) {
- localStorage.setItem("languagePreference", cookieLanguage);
- } else if (localStorageLanguage) {
- cookieManager.set("languagePreference", localStorageLanguage);
+ if (storageLanguage !== localStorageLanguage) {
+ if (storageLanguage) {
+ localStorage.setItem("languagePreference", storageLanguage);
+ } else if (localStorageLanguage) {
+ await storageManager.set("languagePreference", localStorageLanguage);
+ }
}
+ } catch (error) {
+ console.error("Error initializing language:", error);
+ await setLanguage("hu");
+ loadTranslationsForPage();
}
}
@@ -121,8 +127,7 @@
function loadTranslationsForPage() {
try {
applyTranslations();
-
- // Figyeljük a DOM változásokat és alkalmazzuk a fordításokat új elemekre
+
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'childList') {
@@ -142,8 +147,7 @@
}
}
});
-
- // Ha maga az elem is tartalmaz data-i18n attribútumot
+
if (node.hasAttribute && node.hasAttribute('data-i18n')) {
const key = node.getAttribute('data-i18n');
const translation = getTranslation(key);
diff --git a/global/navigation.js b/global/navigation.js
index 24347e7..e06d7d6 100644
--- a/global/navigation.js
+++ b/global/navigation.js
@@ -11,16 +11,16 @@ const DEFAULT_VALUES = {
TIMER: "45:00",
};
-function updateHeaderInfo() {
+async function updateHeaderInfo() {
const schoolName = document.querySelector(".nav-school-name");
const userName = document.querySelector(".nav-user-name");
const logoutTimer = document.querySelector(".nav-logout-timer");
const userData = {
schoolName:
- cookieManager.get(COOKIE_KEYS.SCHOOL_NAME) || DEFAULT_VALUES.SCHOOL,
- schoolId: cookieManager.get(COOKIE_KEYS.SCHOOL_CODE) || "",
- name: cookieManager.get(COOKIE_KEYS.USER_NAME) || DEFAULT_VALUES.USER,
+ await storageManager.get("schoolName", DEFAULT_VALUES.SCHOOL),
+ schoolId: await storageManager.get("schoolCode", ""),
+ name: await storageManager.get("userName", DEFAULT_VALUES.USER),
time:
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
DEFAULT_VALUES.TIMER,
@@ -59,8 +59,8 @@ function startLogoutTimer(timeString) {
setInterval(updateTimer, 1000);
}
-document.addEventListener("DOMContentLoaded", () => {
- updateHeaderInfo();
+document.addEventListener("DOMContentLoaded", async () => {
+ await updateHeaderInfo();
});
function setupUserDropdown() {
@@ -169,8 +169,8 @@ function setupMobileNavigation() {
}, 100);
}
-document.addEventListener("DOMContentLoaded", () => {
- updateHeaderInfo();
+document.addEventListener("DOMContentLoaded", async () => {
+ await updateHeaderInfo();
setupUserDropdown();
setupSettingsButton();
setupMobileNavigation();
diff --git a/global/theme.js b/global/theme.js
index e09df5f..b9b30e5 100644
--- a/global/theme.js
+++ b/global/theme.js
@@ -1,10 +1,12 @@
(() => {
- function setTheme(theme) {
+ async function setTheme(theme) {
try {
const actualTheme = theme === "default" ? "light-blue" : theme;
document.documentElement.setAttribute("data-theme", actualTheme);
- cookieManager.set("themePreference", actualTheme);
+
+ await storageManager.set("themePreference", actualTheme);
+
localStorage.setItem("themePreference", actualTheme);
chrome.runtime
@@ -104,22 +106,29 @@
}
}
- function initializeTheme() {
- const cookieTheme = cookieManager.get("themePreference");
- const localStorageTheme = localStorage.getItem("themePreference");
+ async function initializeTheme() {
+ try {
+ const storageTheme = await storageManager.get("themePreference");
+ const localStorageTheme = localStorage.getItem("themePreference");
- const theme = cookieTheme || localStorageTheme || "light-green";
+ const theme = storageTheme || localStorageTheme || "light-green";
- setTheme(theme);
- setPageTitleAndFavicon();
- importFonts();
+ await setTheme(theme);
+ setPageTitleAndFavicon();
+ importFonts();
- if (cookieTheme !== localStorageTheme) {
- if (cookieTheme) {
- localStorage.setItem("themePreference", cookieTheme);
- } else if (localStorageTheme) {
- cookieManager.set("themePreference", localStorageTheme);
+ if (storageTheme !== localStorageTheme) {
+ if (storageTheme) {
+ localStorage.setItem("themePreference", storageTheme);
+ } else if (localStorageTheme) {
+ await storageManager.set("themePreference", localStorageTheme);
+ }
}
+ } catch (error) {
+ console.error("Error initializing theme:", error);
+ await setTheme("light-green");
+ setPageTitleAndFavicon();
+ importFonts();
}
}
@@ -146,17 +155,21 @@
let titleCheckTimeout;
- const observer = new MutationObserver((mutations) => {
+ const observer = new MutationObserver(async (mutations) => {
const currentTheme = document.documentElement.getAttribute("data-theme");
- const savedTheme =
- cookieManager.get("themePreference") ||
- localStorage.getItem("themePreference");
+
+ try {
+ const savedTheme = await storageManager.get("themePreference") ||
+ localStorage.getItem("themePreference");
- if (
- (!currentTheme && savedTheme) ||
- (currentTheme !== savedTheme && savedTheme)
- ) {
- setTheme(savedTheme);
+ if (
+ (!currentTheme && savedTheme) ||
+ (currentTheme !== savedTheme && savedTheme)
+ ) {
+ await setTheme(savedTheme);
+ }
+ } catch (error) {
+ console.error("Error checking theme in observer:", error);
}
const titleChanged = mutations.some(
diff --git a/grades/grades.js b/grades/grades.js
index 3ff6b13..b343020 100644
--- a/grades/grades.js
+++ b/grades/grades.js
@@ -11,7 +11,7 @@
window.currentGradesData = gradesData;
document.body.innerHTML = '';
const parser = new DOMParser();
- const doc = parser.parseFromString(generatePageHTML(
+ const doc = parser.parseFromString(await generatePageHTML(
gradesData,
studentAverage,
classAverage,
@@ -61,24 +61,24 @@
}
const data = await response.json();
- return processAPIGradesData(data);
+ return await processAPIGradesData(data);
} catch (error) {
console.error("Error fetching grades from API:", error);
- return extractGradesDataFromDOM();
+ return await extractGradesDataFromDOM();
}
}
- function processAPIGradesData(apiData) {
+ async function processAPIGradesData(apiData) {
const subjects = [];
if (!apiData.Data || !Array.isArray(apiData.Data)) {
return {
schoolInfo: {
- id: cookieManager.get("schoolCode") || "",
- name: cookieManager.get("schoolName") || "Iskola",
+ id: await storageManager.get("schoolCode", ""),
+ name: await storageManager.get("schoolName", "OM azonosító - Iskola neve"),
},
userData: {
- name: cookieManager.get("userName") || "Felhasználó",
+ name: await storageManager.get("userName", "Felhasználónév"),
time:
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
"45:00",
@@ -195,11 +195,11 @@
return {
schoolInfo: {
- id: cookieManager.get("schoolCode") || "",
- name: cookieManager.get("schoolName") || "Iskola",
+ id: await storageManager.get("schoolCode", ""),
+ name: await storageManager.get("schoolName", "Iskola"),
},
userData: {
- name: cookieManager.get("userName") || "Felhasználó",
+ name: await storageManager.get("userName", "Felhasználó"),
time:
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
"45:00",
@@ -208,7 +208,7 @@
};
}
- function extractGradesDataFromDOM() {
+ async function extractGradesDataFromDOM() {
const subjects = [];
const rows = document.querySelectorAll(
"#Osztalyzatok_7895TanuloErtekelesByTanuloGrid tbody tr",
@@ -293,11 +293,11 @@
return {
schoolInfo: {
- id: cookieManager.get("schoolCode") || "",
- name: cookieManager.get("schoolName") || "Iskola",
+ id: await storageManager.get("schoolCode", ""),
+ name: await storageManager.get("schoolName", "Iskola"),
},
userData: {
- name: cookieManager.get("userName") || "Felhasználó",
+ name: await storageManager.get("userName", "Felhasználó"),
time:
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
"45:00",
@@ -376,7 +376,7 @@
return distribution;
}
- function generatePageHTML(data, studentAverage, classAverage) {
+ async function generatePageHTML(data, studentAverage, classAverage) {
const totalGrades = data.subjects.reduce(
(sum, subject) => sum + subject.grades.length,
0,
@@ -393,7 +393,7 @@
return `
- ${createTemplate.header()}
+ ${await createTemplate.header()}
diff --git a/homework/homework.js b/homework/homework.js
index c01a2d2..135f832 100644
--- a/homework/homework.js
+++ b/homework/homework.js
@@ -29,11 +29,11 @@ async function collectHomeworkData() {
const basicData = {
schoolInfo: {
- name: cookieManager.get("schoolName") || "Iskola",
- id: cookieManager.get("schoolCode") || "",
+ name: await storageManager.get("schoolName", "OM azonosító - Iskola neve"),
+ id: await storageManager.get("schoolCode", ""),
},
userData: {
- name: cookieManager.get("userName") || "Felhasználó",
+ name: await storageManager.get("userName", "Felhasználónév"),
time:
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
"45:00",
@@ -124,7 +124,7 @@ async function transformHomeworkPage() {
kretaContainer.className = 'kreta-container';
const headerDiv = document.createElement('div');
const parser = new DOMParser();
- const headerDoc = parser.parseFromString(createTemplate.header(), 'text/html');
+ const headerDoc = parser.parseFromString(await createTemplate.header(), 'text/html');
const headerContent = headerDoc.body;
while (headerContent.firstChild) {
headerDiv.appendChild(headerContent.firstChild);
@@ -624,28 +624,28 @@ function updateDateGroupsVisibility() {
});
}
-function getHomeworkCompletionStatus(homeworkId) {
- const completedHomework = cookieManager.get('completedHomework');
+async function getHomeworkCompletionStatus(homeworkId) {
+ const completedHomework = await storageManager.get('completedHomework');
if (!completedHomework) return false;
try {
const completedList = JSON.parse(completedHomework);
return completedList.includes(homeworkId.toString());
} catch (error) {
- console.error('Error parsing completed homework cookie:', error);
+ console.error('Error parsing completed homework storage:', error);
return false;
}
}
-function setHomeworkCompletionStatus(homeworkId, isCompleted) {
- let completedHomework = cookieManager.get('completedHomework');
+async function setHomeworkCompletionStatus(homeworkId, isCompleted) {
+ let completedHomework = await storageManager.get('completedHomework');
let completedList = [];
if (completedHomework) {
try {
completedList = JSON.parse(completedHomework);
} catch (error) {
- console.error('Error parsing completed homework cookie:', error);
+ console.error('Error parsing completed homework storage:', error);
completedList = [];
}
}
@@ -660,7 +660,7 @@ function setHomeworkCompletionStatus(homeworkId, isCompleted) {
completedList = completedList.filter(id => id !== homeworkIdStr);
}
- cookieManager.set('completedHomework', JSON.stringify(completedList));
+ await storageManager.set('completedHomework', JSON.stringify(completedList));
}
function setupHomeworkCheckboxes() {
diff --git a/logout/logout.js b/logout/logout.js
index 132d68b..7d4adf9 100644
--- a/logout/logout.js
+++ b/logout/logout.js
@@ -1,10 +1,10 @@
(() => {
- function transformLogoutPage() {
+ async function transformLogoutPage() {
const theme =
- cookieManager.get("themePreference") ||
+ await storageManager.get("themePreference", null) ||
localStorage.getItem("themePreference") ||
"light-green";
- const instituteCode = cookieManager.get("schoolSubdomain");
+ const instituteCode = await storageManager.get("schoolSubdomain", null);
document.documentElement.setAttribute("data-theme", theme);
const newHTML = `
diff --git a/manifest.json b/manifest.json
index 23f2b3b..aa53af7 100644
--- a/manifest.json
+++ b/manifest.json
@@ -12,6 +12,12 @@
"128": "images/firka_logo_128.png"
}
},
+ "permissions": [
+ "storage"
+ ],
+ "background": {
+ "service_worker": "tools/background.js"
+ },
"browser_specific_settings": {
"gecko": {
"id": "firxa@zan1456.hu",
@@ -31,7 +37,9 @@
"icons/*.svg",
"grades/chart.js",
"i18n/*.json",
- "tools/cookieManager.js"
+ "tools/cookieManager.js",
+ "tools/storageManager.js",
+ "tools/storageTest.js"
],
"matches": [
"
"
@@ -58,7 +66,7 @@
"global/language.js",
"global/theme.js",
"tools/loadingScreen.js",
- "tools/cookieManager.js",
+ "tools/storageManager.js",
"tools/helper.js",
"tools/createTemplate.js",
"global/maintenance.js",
diff --git a/roleselect/roleselect.js b/roleselect/roleselect.js
index 5f73237..51c5356 100644
--- a/roleselect/roleselect.js
+++ b/roleselect/roleselect.js
@@ -120,12 +120,12 @@
userNameEl?.textContent.trim() || LanguageManager.t("common.username");
if (schoolCode && fullSchoolName) {
- cookieManager.set("schoolCode", schoolCode);
- cookieManager.set("schoolName", fullSchoolName);
- cookieManager.set("schoolSubdomain", schoolSubdomain);
+ await storageManager.set("schoolCode", schoolCode);
+ await storageManager.set("schoolName", fullSchoolName);
+ await storageManager.set("schoolSubdomain", schoolSubdomain);
}
if (userName) {
- cookieManager.set("userName", userName);
+ await storageManager.set("userName", userName);
}
document.body.innerHTML = '';
const parser = new DOMParser();
diff --git a/search/search.js b/search/search.js
index da311e8..e3633e6 100644
--- a/search/search.js
+++ b/search/search.js
@@ -20,10 +20,10 @@ if (
setTimeout(initializeTransformation, 1000);
}
-function applyFirkaStyling() {
+async function applyFirkaStyling() {
try {
const theme =
- cookieManager.get("themePreference") ||
+ await storageManager.get("themePreference") ||
localStorage.getItem("themePreference") ||
"light-green";
document.documentElement.setAttribute("data-theme", theme);
diff --git a/timetable/timetable.js b/timetable/timetable.js
index 4901226..5cdad73 100644
--- a/timetable/timetable.js
+++ b/timetable/timetable.js
@@ -1,8 +1,8 @@
(() => {
- function getCompletedHomework() {
- if (typeof cookieManager !== 'undefined') {
+ async function getCompletedHomework() {
+ if (typeof storageManager !== 'undefined') {
try {
- const value = cookieManager.get('completedHomework');
+ const value = await storageManager.get('completedHomework');
if (value) {
return JSON.parse(value);
}
@@ -13,14 +13,14 @@
return [];
}
- function saveCompletedHomework(completedList) {
- if (typeof cookieManager !== 'undefined') {
- cookieManager.set('completedHomework', JSON.stringify(completedList), 365);
+ async function saveCompletedHomework(completedList) {
+ if (typeof storageManager !== 'undefined') {
+ await storageManager.set('completedHomework', JSON.stringify(completedList));
}
}
- function toggleHomeworkCompletion(lessonId) {
- const completed = getCompletedHomework();
+ async function toggleHomeworkCompletion(lessonId) {
+ const completed = await getCompletedHomework();
const index = completed.indexOf(lessonId);
if (index > -1) {
@@ -29,19 +29,20 @@
completed.push(lessonId);
}
- saveCompletedHomework(completed);
+ await saveCompletedHomework(completed);
return index === -1;
}
- function isHomeworkCompleted(lessonId) {
- return getCompletedHomework().includes(lessonId);
+ async function isHomeworkCompleted(lessonId) {
+ const completed = await getCompletedHomework();
+ return completed.includes(lessonId);
}
- function getCustomHomework() {
- if (typeof cookieManager !== 'undefined') {
+ async function getCustomHomework() {
+ if (typeof storageManager !== 'undefined') {
try {
- const value = cookieManager.get('customHomework');
+ const value = await storageManager.get('customHomework');
if (value) {
return JSON.parse(value);
}
@@ -52,16 +53,16 @@
return {};
}
- function saveCustomHomework(customHomework) {
- if (typeof cookieManager !== 'undefined') {
- cookieManager.set('customHomework', JSON.stringify(customHomework), 365);
+ async function saveCustomHomework(customHomework) {
+ if (typeof storageManager !== 'undefined') {
+ await storageManager.set('customHomework', JSON.stringify(customHomework));
}
}
- function getCustomTests() {
- if (typeof cookieManager !== 'undefined') {
+ async function getCustomTests() {
+ if (typeof storageManager !== 'undefined') {
try {
- const value = cookieManager.get('customTests');
+ const value = await storageManager.get('customTests');
if (value) {
return JSON.parse(value);
}
@@ -72,9 +73,9 @@
return {};
}
- function saveCustomTests(customTests) {
- if (typeof cookieManager !== 'undefined') {
- cookieManager.set('customTests', JSON.stringify(customTests), 365);
+ async function saveCustomTests(customTests) {
+ if (typeof storageManager !== 'undefined') {
+ await storageManager.set('customTests', JSON.stringify(customTests));
}
}
@@ -162,8 +163,8 @@
return `${lesson.subject}_${lesson.startTime}_${lesson.day}`;
}
- function updateHomeworkIconsFromCookie() {
- const completedHomework = getCompletedHomework();
+ async function updateHomeworkIconsFromCookie() {
+ const completedHomework = await getCompletedHomework();
completedHomework.forEach(lessonId => {
const lessonCards = document.querySelectorAll(`[data-lesson-id="${lessonId}"]`);
lessonCards.forEach(card => {
@@ -2206,11 +2207,11 @@
const lessons = convertAPIDataToLessons(apiData, weekDates);
const data = {
schoolInfo: {
- name: cookieManager.get("schoolName") || "Iskola",
- id: cookieManager.get("schoolCode") || "",
+ name: await storageManager.get("schoolName", "OM azonosító - Iskola neve"),
+ id: await storageManager.get("schoolCode", ""),
},
userData: {
- name: cookieManager.get("userName") || "Felhasználó",
+ name: await storageManager.get("userName", "Felhasználónév"),
time: "45:00",
},
weekInfo: {
@@ -2232,7 +2233,7 @@
const headerDiv = document.createElement('div');
const parser2 = new DOMParser();
- const headerDoc = parser2.parseFromString(createTemplate.header(), 'text/html');
+ const headerDoc = parser2.parseFromString(await createTemplate.header(), 'text/html');
const headerContent = headerDoc.body;
while (headerContent.firstChild) {
headerDiv.appendChild(headerContent.firstChild);
@@ -2390,8 +2391,8 @@
timetableContainer.appendChild(timetableGrid);
- setTimeout(() => {
- updateHomeworkIconsFromCookie();
+ setTimeout(async () => {
+ await updateHomeworkIconsFromCookie();
}, 100);
main.appendChild(weekControls);
@@ -2403,8 +2404,12 @@
document.body.appendChild(kretaContainer);
- setupUserDropdown();
- setupMobileNavigation();
+ if (typeof setupUserDropdown === 'function') {
+ setupUserDropdown();
+ }
+ if (typeof setupMobileNavigation === 'function') {
+ setupMobileNavigation();
+ }
setupEventListeners(data);
initializeWeekSelector();
@@ -2549,8 +2554,8 @@
}
setupLessonCardListeners();
- setTimeout(() => {
- updateHomeworkIconsFromCookie();
+ setTimeout(async () => {
+ await updateHomeworkIconsFromCookie();
}, 100);
}
})
diff --git a/tools/background.js b/tools/background.js
new file mode 100644
index 0000000..683d691
--- /dev/null
+++ b/tools/background.js
@@ -0,0 +1,106 @@
+chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
+ (async () => {
+ try {
+ switch (request.action) {
+ case 'storage_set':
+ await handleStorageSet(request.key, request.value);
+ sendResponse({ success: true });
+ break;
+
+ case 'storage_get':
+ const value = await handleStorageGet(request.key, request.defaultValue);
+ sendResponse({ success: true, value: value });
+ break;
+
+ case 'storage_remove':
+ await handleStorageRemove(request.key);
+ sendResponse({ success: true });
+ break;
+
+ case 'storage_clear':
+ await handleStorageClear();
+ sendResponse({ success: true });
+ break;
+
+ default:
+ console.warn('[Background] Unknown action:', request.action);
+ sendResponse({ success: false, error: 'Unknown action' });
+ }
+ } catch (error) {
+ console.error('[Background] Error handling message:', error);
+ sendResponse({ success: false, error: error.message });
+ }
+ })();
+ return true;
+});
+
+async function handleStorageSet(key, value) {
+ try {
+ await chrome.storage.sync.set({ [key]: value });
+ } catch (error) {
+ console.error(`[Background] Failed to save ${key}:`, error);
+ throw error;
+ }
+}
+
+async function handleStorageGet(key, defaultValue = null) {
+ try {
+ const result = await chrome.storage.sync.get(key);
+ const value = result[key];
+ return value !== undefined ? value : defaultValue;
+ } catch (error) {
+ console.error(`[Background] Failed to get ${key}:`, error);
+ throw error;
+ }
+}
+
+async function handleStorageRemove(key) {
+ try {
+ await chrome.storage.sync.remove(key);
+ } catch (error) {
+ console.error(`[Background] Failed to remove ${key}:`, error);
+ throw error;
+ }
+}
+
+async function handleStorageClear() {
+ try {
+ const allData = await chrome.storage.sync.get(null);
+ const firkaKeys = Object.keys(allData).filter(key => key.startsWith('firka_'));
+
+ if (firkaKeys.length > 0) {
+ await chrome.storage.sync.remove(firkaKeys);
+ }
+ } catch (error) {
+ console.error('[Background] Failed to clear storage:', error);
+ throw error;
+ }
+}
+
+chrome.storage.onChanged.addListener((changes, namespace) => {
+ if (namespace === 'sync') {
+ const firkaChanges = Object.keys(changes).filter(key => key.startsWith('firka_'));
+ if (firkaChanges.length > 0) {
+ notifyContentScriptsOfChanges(changes);
+ }
+ }
+});
+
+async function notifyContentScriptsOfChanges(changes) {
+ try {
+ const tabs = await chrome.tabs.query({ url: 'https://*.e-kreta.hu/*' });
+
+ for (const tab of tabs) {
+ try {
+ await chrome.tabs.sendMessage(tab.id, {
+ action: 'storage_changed',
+ changes: changes
+ });
+ } catch (error) {
+ console.debug(`[Background] Could not notify tab ${tab.id}:`, error.message);
+ }
+ }
+ } catch (error) {
+ console.error('[Background] Failed to notify content scripts:', error);
+ }
+}
\ No newline at end of file
diff --git a/tools/cookieManager.js b/tools/cookieManager.js
deleted file mode 100644
index edbe1e5..0000000
--- a/tools/cookieManager.js
+++ /dev/null
@@ -1,25 +0,0 @@
-const cookieManager = {
- get(name) {
- const cookieName = `${name}=`;
- const decodedCookie = decodeURIComponent(document.cookie);
- const cookieArray = decodedCookie.split(";");
-
- for (let i = 0; i < cookieArray.length; i++) {
- let cookie = cookieArray[i];
- while (cookie.charAt(0) === " ") {
- cookie = cookie.substring(1);
- }
- if (cookie.indexOf(cookieName) === 0) {
- return cookie.substring(cookieName.length, cookie.length);
- }
- }
- return null;
- },
-
- set(name, value, days = 365) {
- const date = new Date();
- date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
- const expires = `expires=${date.toUTCString()}`;
- document.cookie = `${name}=${value}; ${expires}; path=/; domain=.e-kreta.hu`;
- },
-};
diff --git a/tools/createTemplate.js b/tools/createTemplate.js
index 8e34b20..9113ed3 100644
--- a/tools/createTemplate.js
+++ b/tools/createTemplate.js
@@ -1,16 +1,15 @@
const createTemplate = {
- header() {
+ async header() {
const data = {
schoolInfo: {
- name: cookieManager.get("schoolName") || "Iskola",
- id: cookieManager.get("schoolCode") || "",
+ name: await storageManager.get("schoolName", "OM azonosító - Iskola neve"),
+ id: await storageManager.get("schoolCode", ""),
},
userData: {
- name: cookieManager.get("userName") || "Felhasználó",
+ name: await storageManager.get("userName", "Felhasználónév"),
time:
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
"45:00",
- email: cookieManager.get("userEmail") || "",
},
};
diff --git a/tools/storageManager.js b/tools/storageManager.js
new file mode 100644
index 0000000..b5d9a27
--- /dev/null
+++ b/tools/storageManager.js
@@ -0,0 +1,193 @@
+const storageManager = {
+ isExtensionContext() {
+ return typeof chrome !== 'undefined' && chrome.runtime && chrome.runtime.id;
+ },
+
+ isContentScript() {
+ return typeof chrome !== 'undefined' && chrome.runtime && chrome.runtime.sendMessage;
+ },
+
+ async set(key, value) {
+ const prefixedKey = `firka_${key}`;
+
+ try {
+ if (this.isExtensionContext()) {
+ await chrome.storage.sync.set({ [prefixedKey]: value });
+ } else if (this.isContentScript()) {
+ return new Promise((resolve, reject) => {
+ chrome.runtime.sendMessage({
+ action: 'storage_set',
+ key: prefixedKey,
+ value: value
+ }, (response) => {
+ if (chrome.runtime.lastError) {
+ reject(chrome.runtime.lastError);
+ } else if (response && response.success) {
+ resolve();
+ } else {
+ reject(new Error('Failed to save via message passing'));
+ }
+ });
+ });
+ } else {
+ localStorage.setItem(prefixedKey, JSON.stringify(value));
+ }
+ } catch (error) {
+ console.warn(`[StorageManager] Primary storage failed for ${key}, falling back to cookie:`, error);
+ if (typeof cookieManager !== 'undefined') {
+ cookieManager.set(prefixedKey, JSON.stringify(value));
+ }
+ }
+ },
+
+ async get(key, defaultValue = null) {
+ const prefixedKey = `firka_${key}`;
+
+ try {
+ if (this.isExtensionContext()) {
+ const result = await chrome.storage.sync.get(prefixedKey);
+ const value = result[prefixedKey];
+ return value !== undefined ? value : defaultValue;
+ } else if (this.isContentScript()) {
+ return new Promise((resolve, reject) => {
+ chrome.runtime.sendMessage({
+ action: 'storage_get',
+ key: prefixedKey,
+ defaultValue: defaultValue
+ }, (response) => {
+ if (chrome.runtime.lastError) {
+ reject(chrome.runtime.lastError);
+ } else if (response && response.hasOwnProperty('value')) {
+ resolve(response.value);
+ } else {
+ reject(new Error('Failed to get via message passing'));
+ }
+ });
+ });
+ } else {
+ const value = localStorage.getItem(prefixedKey);
+ if (value !== null) {
+ return JSON.parse(value);
+ }
+ return defaultValue;
+ }
+ } catch (error) {
+ console.warn(`[StorageManager] Primary storage failed for ${key}, falling back to cookie:`, error);
+ if (typeof cookieManager !== 'undefined') {
+ const cookieValue = cookieManager.get(prefixedKey);
+ if (cookieValue) {
+ try {
+ return JSON.parse(cookieValue);
+ } catch (parseError) {
+ return cookieValue;
+ }
+ }
+ }
+ return defaultValue;
+ }
+ },
+
+ async remove(key) {
+ const prefixedKey = `firka_${key}`;
+
+ try {
+ if (this.isExtensionContext()) {
+ await chrome.storage.sync.remove(prefixedKey);
+ } else if (this.isContentScript()) {
+ return new Promise((resolve, reject) => {
+ chrome.runtime.sendMessage({
+ action: 'storage_remove',
+ key: prefixedKey
+ }, (response) => {
+ if (chrome.runtime.lastError) {
+ reject(chrome.runtime.lastError);
+ } else if (response && response.success) {
+ resolve();
+ } else {
+ reject(new Error('Failed to remove via message passing'));
+ }
+ });
+ });
+ } else {
+ localStorage.removeItem(prefixedKey);
+ }
+ } catch (error) {
+ console.warn(`[StorageManager] Failed to remove ${key}:`, error);
+ }
+ },
+
+ async clear() {
+ try {
+ if (this.isExtensionContext()) {
+ const allData = await chrome.storage.sync.get(null);
+ const firkaKeys = Object.keys(allData).filter(key => key.startsWith('firka_'));
+ if (firkaKeys.length > 0) {
+ await chrome.storage.sync.remove(firkaKeys);
+ }
+ } else if (this.isContentScript()) {
+ return new Promise((resolve, reject) => {
+ chrome.runtime.sendMessage({
+ action: 'storage_clear'
+ }, (response) => {
+ if (chrome.runtime.lastError) {
+ reject(chrome.runtime.lastError);
+ } else if (response && response.success) {
+ resolve();
+ } else {
+ reject(new Error('Failed to clear via message passing'));
+ }
+ });
+ });
+ } else {
+ const keysToRemove = [];
+ for (let i = 0; i < localStorage.length; i++) {
+ const key = localStorage.key(i);
+ if (key && key.startsWith('firka_')) {
+ keysToRemove.push(key);
+ }
+ }
+ keysToRemove.forEach(key => localStorage.removeItem(key));
+ }
+ } catch (error) {
+ console.warn('[StorageManager] Failed to clear storage:', error);
+ }
+ },
+
+ async migrateFromCookies() {
+ if (typeof cookieManager === 'undefined') {
+ return;
+ }
+
+ const knownSettings = [
+ 'theme', 'language', 'notifications', 'autoRefresh',
+ 'compactMode', 'showGrades', 'showAbsences'
+ ];
+
+ let migratedCount = 0;
+
+ for (const setting of knownSettings) {
+ try {
+ const cookieValue = cookieManager.get(`firka_${setting}`);
+ if (cookieValue !== null) {
+ let value;
+ try {
+ value = JSON.parse(cookieValue);
+ } catch {
+ value = cookieValue;
+ }
+
+ await this.set(setting, value);
+ migratedCount++;
+ }
+ } catch (error) {
+ console.warn(`[StorageManager] Failed to migrate ${setting}:`, error);
+ }
+ }
+ }
+};
+
+if (typeof document !== 'undefined') {
+ document.addEventListener('DOMContentLoaded', () => {
+ storageManager.migrateFromCookies().catch(console.error);
+ });
+}
\ No newline at end of file