From f6a52b73def2e8fe7438a4faacdf7ae594923d45 Mon Sep 17 00:00:00 2001
From: Zan <62830223+Zan1456@users.noreply.github.com>
Date: Wed, 10 Dec 2025 15:51:37 +0100
Subject: [PATCH] firefox addon store bullshit
---
absences/absences.js | 6 +-
dashboard/dashboard.js | 14 +-
forgotpassword/forgotpassword.css | 57 ----
forgotpassword/forgotpassword.js | 290 --------------------
global/maintenance.js | 2 +-
grades/grades.js | 17 +-
login/login.js | 12 +-
login/twofactor.js | 15 +-
logout/logout.js | 8 +-
messages/messages.js | 428 +++++++++++++++++++++---------
profile/profile.js | 2 +-
roleselect/roleselect.js | 10 +-
settings/index.js | 38 ++-
timetable/timetable.js | 79 ++++--
tools/helper.js | 24 ++
15 files changed, 451 insertions(+), 551 deletions(-)
delete mode 100644 forgotpassword/forgotpassword.css
delete mode 100644 forgotpassword/forgotpassword.js
diff --git a/absences/absences.js b/absences/absences.js
index 5bf0443..c72686e 100644
--- a/absences/absences.js
+++ b/absences/absences.js
@@ -402,9 +402,9 @@ async function transformAbsencesPage() {
container.className = 'kreta-container';
const headerDiv = document.createElement('div');
- const parser = new DOMParser();
- const doc = parser.parseFromString(await createTemplate.header(), 'text/html');
- const tempDiv = doc.body;
+ const template = document.createElement('template');
+ template.innerHTML = await createTemplate.header();
+ const tempDiv = template.content;
while (tempDiv.firstChild) {
headerDiv.appendChild(tempDiv.firstChild);
}
diff --git a/dashboard/dashboard.js b/dashboard/dashboard.js
index 5631c24..115fad3 100644
--- a/dashboard/dashboard.js
+++ b/dashboard/dashboard.js
@@ -499,22 +499,22 @@ class DashboardRenderer {
async render() {
await this.init();
- document.body.innerHTML = '';
+ helper.clearElement(document.body);
const kretaContainer = document.createElement('div');
kretaContainer.className = 'kreta-container';
const headerDiv = document.createElement('div');
- const parser = new DOMParser();
- const headerDoc = parser.parseFromString(await createTemplate.header(), 'text/html');
- const headerContent = headerDoc.body;
+ const template = document.createElement('template');
+ template.innerHTML = await createTemplate.header();
+ const headerContent = template.content;
while (headerContent.firstChild) {
headerDiv.appendChild(headerContent.firstChild);
}
kretaContainer.appendChild(headerDiv);
const mainContentDiv = document.createElement('div');
- const parser2 = new DOMParser();
- const mainDoc = parser2.parseFromString(this.generateMainContent(), 'text/html');
- const mainContent = mainDoc.body;
+ const template2 = document.createElement('template');
+ template2.innerHTML = this.generateMainContent();
+ const mainContent = template2.content;
while (mainContent.firstChild) {
mainContentDiv.appendChild(mainContent.firstChild);
}
diff --git a/forgotpassword/forgotpassword.css b/forgotpassword/forgotpassword.css
deleted file mode 100644
index 33e629f..0000000
--- a/forgotpassword/forgotpassword.css
+++ /dev/null
@@ -1,57 +0,0 @@
-body.maintenance-mode {
- margin:0;
- padding:0;
- height:100vh;
- display:flex;
- align-items:center;
- justify-content:center;
- background-color:var(--background);
- color:var(--text-primary);
- font-family:'Figtree',sans-serif;
-}
-body {
- background-color:var(--background) !important;
-}
-.maintenance-container {
- text-align:center;
- padding:2rem;
- border-radius:8px;
- background-color:var(--card-card);
- box-shadow:0 var(--shadow-blur) 6px var(--accent-shadow);
- max-width:600px;
- width:90%;
-}
-.maintenance-logo {
- width:128px;
- height:128px;
- margin:0 auto 2rem;
-}
-.maintenance-title {
- font-size:1.5rem;
- font-weight:600;
- margin-bottom:1rem;
- color:var(--accent-accent);
- font-family:'Montserrat',sans-serif;
-}
-.maintenance-message {
- font-size:1rem;
- line-height:1.5;
- margin-bottom:1.5rem;
- color:var(--text-primary);
- font-family:'Figtree',sans-serif;
-}
-.maintenance-footer {
- font-size:0.875rem;
- color:var(--text-secondary);
- margin-top:2rem;
- font-family:'Figtree',sans-serif;
-}
-.maintenance-cactus {
- position:fixed;
- bottom:0px;
- right:20px;
- width:120px;
- height:120px;
- opacity:1;
- z-index:1000;
-}
diff --git a/forgotpassword/forgotpassword.js b/forgotpassword/forgotpassword.js
deleted file mode 100644
index 5ab9ab6..0000000
--- a/forgotpassword/forgotpassword.js
+++ /dev/null
@@ -1,290 +0,0 @@
-(() => {
- // reCAPTCHA functionality removed for security compliance
-
- const loadDependencies = async () => {
- // reCAPTCHA functionality removed for security compliance
- // Extension now works without external script dependencies
- };
-
- const createPageStructure = () => {
- // Biztonságos DOM létrehozás innerHTML helyett
- document.body.innerHTML = '';
- // Biztonságos HTML parsing DOMParser használatával
- const parser = new DOMParser();
- const doc = parser.parseFromString(`
-
-
-
-
-
-
-
-
-
-
-
Elfelejtett jelszó
-
-
-
-
- `, 'text/html');
- const tempDiv = doc.body;
-
- // Biztonságos DOM hozzáadás
- while (tempDiv.firstChild) {
- document.body.appendChild(tempDiv.firstChild);
- }
- };
-
- const transformForgotPasswordPage = async () => {
- await loadDependencies();
-
- const isDarkMode = localStorage.getItem("darkMode") === "true";
- document.documentElement.setAttribute(
- "data-theme",
- isDarkMode ? "dark" : "light",
- );
-
- chrome.runtime.onMessage.addListener((message) => {
- if (message.action === "toggleTheme") {
- document.documentElement.setAttribute(
- "data-theme",
- message.darkMode ? "dark" : "light",
- );
- localStorage.setItem("darkMode", message.darkMode);
- }
- });
-
- createPageStructure();
-
- let attempts = 0;
- const maxAttempts = 50;
-
- const waitForLanguageManager = () => {
- return new Promise((resolve) => {
- const checkLanguageManager = () => {
- attempts++;
- if (typeof LanguageManager !== "undefined" && LanguageManager.t) {
- setTimeout(resolve, 200);
- } else if (attempts < maxAttempts) {
- setTimeout(checkLanguageManager, 100);
- } else {
- console.warn("LanguageManager not available, using fallback texts");
- resolve();
- }
- };
- checkLanguageManager();
- });
- };
-
- await waitForLanguageManager();
-
- if (typeof LanguageManager !== "undefined" && LanguageManager.t) {
- const elements = document.querySelectorAll("[data-i18n]");
- elements.forEach((element) => {
- const key = element.getAttribute("data-i18n");
- const translation = LanguageManager.t(key);
-
- if (translation && translation !== key) {
- const attr = element.getAttribute("data-i18n-attr");
- if (attr) {
- element.setAttribute(attr, translation);
- } else {
- element.textContent = translation;
- }
- }
- });
- }
-
- // reCAPTCHA rendering removed for security compliance
-
- setupFormValidation();
- };
-
- const setupFormValidation = () => {
- const form = document.getElementById("forgotForm");
- const inputs = form.querySelectorAll(".form-control");
-
- inputs.forEach((input) => {
- input.addEventListener("input", () => {
- validateInput(input);
- });
-
- input.addEventListener("blur", () => {
- validateInput(input, true);
- });
- });
-
- form.addEventListener("submit", handleSubmit);
- };
-
- const validateInput = (input, showError = false) => {
- const isValid = input.value.trim().length > 0;
- const errorElement = input.nextElementSibling;
-
- if (!isValid && showError) {
- input.classList.add("error");
- errorElement?.classList.add("show");
- } else {
- input.classList.remove("error");
- errorElement?.classList.remove("show");
- }
-
- return isValid;
- };
-
- const showMessage = (message, isError = false) => {
- const existingMessage = document.querySelector(".message");
- if (existingMessage) {
- existingMessage.remove();
- }
-
- const messageDiv = document.createElement("div");
- messageDiv.className = `message ${isError ? "error" : "success"}`;
- messageDiv.textContent = message;
-
- const form = document.getElementById("forgotForm");
- form.insertBefore(messageDiv, form.firstChild);
-
- setTimeout(() => {
- if (messageDiv.parentNode) {
- messageDiv.remove();
- }
- }, 5000);
- };
-
- const validateEmail = (email) => {
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
- return emailRegex.test(email);
- };
-
- const handleSubmit = async (event) => {
- event.preventDefault();
-
- const form = event.target;
- const inputs = form.querySelectorAll(".form-control[required]");
- let isValid = true;
-
- inputs.forEach((input) => {
- if (!validateInput(input, true)) {
- isValid = false;
- }
- });
-
- const emailInput = form.querySelector("#EmailCim");
- if (emailInput.value && !validateEmail(emailInput.value)) {
- emailInput.classList.add("error");
- const errorElement = emailInput.nextElementSibling;
- if (errorElement) {
- errorElement.textContent = LanguageManager.t(
- "forgotpassword.invalid_email",
- );
- errorElement.classList.add("show");
- }
- isValid = false;
- }
-
- // reCAPTCHA validation removed for security compliance
-
- if (!isValid) {
- return;
- }
-
- const submitButton = form.querySelector(".btn-submit");
- const originalText = submitButton.textContent;
- submitButton.disabled = true;
- submitButton.textContent = LanguageManager.t("loading.text") || "Küldés...";
-
- try {
- const formData = new FormData(form);
-
- // reCAPTCHA data removed for security compliance
-
- const response = await fetch(
- "/Adminisztracio/ElfelejtettJelszo/LinkKuldes",
- {
- method: "POST",
- body: formData,
- headers: {
- "X-Requested-With": "XMLHttpRequest",
- },
- },
- );
-
- if (!response.ok) {
- throw new Error(`HTTP error! status: ${response.status}`);
- }
-
- const result = await response.json();
-
- if (result.Success) {
- showMessage(LanguageManager.t("forgotpassword.success_message"));
-
- form.reset();
-
- // reCAPTCHA reset removed
-
- setTimeout(() => {
- window.location.href = "/Adminisztracio/Login";
- }, 3000);
- } else {
- showMessage(
- result.Message || LanguageManager.t("forgotpassword.error_message"),
- true,
- );
-
- // reCAPTCHA reset removed
- }
- } catch (error) {
- console.error("Password reset error:", error);
- showMessage(LanguageManager.t("forgotpassword.error_message"), true);
-
- // reCAPTCHA reset removed
- } finally {
- submitButton.disabled = false;
- submitButton.textContent = originalText;
- }
- };
-
- if (window.location.href.includes("/Adminisztracio/ElfelejtettJelszo")) {
- transformForgotPasswordPage().catch(console.error);
- }
-})();
diff --git a/global/maintenance.js b/global/maintenance.js
index 9f5ef33..adaa7d0 100644
--- a/global/maintenance.js
+++ b/global/maintenance.js
@@ -45,7 +45,7 @@ function checkMaintenancePage() {
);
existingStyles.forEach((style) => style.remove());
- body.innerHTML = "";
+ helper.clearElement(body);
body.classList.add("maintenance-mode");
body.classList.add("theme-enabled");
body.classList.add("loaded");
diff --git a/grades/grades.js b/grades/grades.js
index 94e1c16..fcee35a 100644
--- a/grades/grades.js
+++ b/grades/grades.js
@@ -28,17 +28,18 @@
const classAverage = calculateOverallClassAverage(gradesData.subjects);
window.currentGradesData = gradesData;
- document.body.innerHTML = '';
- const parser = new DOMParser();
- const doc = parser.parseFromString(await generatePageHTML(
+
+ const htmlString = await generatePageHTML(
gradesData,
studentAverage,
classAverage,
- ), 'text/html');
- const tempDiv = doc.body;
- while (tempDiv.firstChild) {
- document.body.appendChild(tempDiv.firstChild);
- }
+ );
+
+ const template = document.createElement('template');
+ template.innerHTML = htmlString;
+
+ helper.clearElement(document.body);
+ document.body.appendChild(template.content);
setupUserDropdown();
diff --git a/login/login.js b/login/login.js
index 044c925..3fa2e7b 100644
--- a/login/login.js
+++ b/login/login.js
@@ -120,13 +120,11 @@ async function transformLoginPage() {
`;
- document.body.innerHTML = '';
- const parser = new DOMParser();
- const doc = parser.parseFromString(newHTML, 'text/html');
- const tempDiv = doc.body;
- while (tempDiv.firstChild) {
- document.body.appendChild(tempDiv.firstChild);
- }
+ const template = document.createElement('template');
+ template.innerHTML = newHTML;
+
+ helper.clearElement(document.body);
+ document.body.appendChild(template.content);
setupEventListeners();
} catch (error) {
diff --git a/login/twofactor.js b/login/twofactor.js
index b925b07..32e9ed9 100644
--- a/login/twofactor.js
+++ b/login/twofactor.js
@@ -83,13 +83,12 @@ async function transformTwoFactorPage() {
`;
- document.body.innerHTML = '';
- const parser = new DOMParser();
- const doc = parser.parseFromString(newHTML, 'text/html');
- const tempDiv = doc.body;
- while (tempDiv.firstChild) {
- document.body.appendChild(tempDiv.firstChild);
- }
+ const template = document.createElement('template');
+ template.innerHTML = newHTML;
+
+ helper.clearElement(document.body);
+ document.body.appendChild(template.content);
+
applyTheme();
setupEventListeners();
if (typeof loadingScreen !== "undefined") {
@@ -170,7 +169,7 @@ function handleSubmit(event) {
const submitButton = form.querySelector(".btn-kreta");
if (submitButton) {
submitButton.disabled = true;
- submitButton.innerHTML = '';
+ helper.clearElement(submitButton);
const spinnerSpan = document.createElement('span');
spinnerSpan.className = 'spinner';
const textSpan = document.createElement('span');
diff --git a/logout/logout.js b/logout/logout.js
index 7d4adf9..c0d47fc 100644
--- a/logout/logout.js
+++ b/logout/logout.js
@@ -34,10 +34,10 @@
`;
- document.body.innerHTML = '';
- const parser = new DOMParser();
- const doc = parser.parseFromString(newHTML, 'text/html');
- const tempDiv = doc.body;
+ helper.clearElement(document.body);
+ const template = document.createElement('template');
+ template.innerHTML = newHTML;
+ const tempDiv = template.content;
while (tempDiv.firstChild) {
document.body.appendChild(tempDiv.firstChild);
}
diff --git a/messages/messages.js b/messages/messages.js
index fce3b8d..9bd3350 100644
--- a/messages/messages.js
+++ b/messages/messages.js
@@ -42,7 +42,7 @@
function sanitizeHTML(html) {
const div = document.createElement('div');
div.textContent = html;
- return div.innerHTML;
+ return div.textContent;
}
class APIManager {
@@ -159,18 +159,32 @@
const modalContent = document.createElement('div');
modalContent.className = 'modal-content';
- modalContent.innerHTML = `
-
-
-
-
-
Üzenet betöltése...
-
-
- `;
+
+ const modalHeader = document.createElement('div');
+ modalHeader.className = 'modal-header';
+ const modalTitle = document.createElement('h2');
+ modalTitle.textContent = 'Üzenet részletei';
+ const modalClose = document.createElement('button');
+ modalClose.className = 'modal-close';
+ modalClose.textContent = '×';
+ modalHeader.appendChild(modalTitle);
+ modalHeader.appendChild(modalClose);
+
+ const modalBody = document.createElement('div');
+ modalBody.className = 'modal-body';
+ const loadingContent = document.createElement('div');
+ loadingContent.className = 'loading-content';
+ const loadingSpinner = document.createElement('div');
+ loadingSpinner.className = 'loading-spinner';
+ const loadingText = document.createElement('p');
+ loadingText.textContent = 'Üzenet betöltése...';
+ loadingContent.appendChild(loadingSpinner);
+ loadingContent.appendChild(loadingText);
+ modalBody.appendChild(loadingContent);
+
+ modalContent.appendChild(modalHeader);
+ modalContent.appendChild(modalBody);
+
modalOverlay.appendChild(modalContent);
document.body.appendChild(modalOverlay);
@@ -213,13 +227,24 @@
console.error('Error loading message details:', error);
const modalContent = document.querySelector('.modal-content');
if (modalContent) {
- modalContent.querySelector('.modal-body').innerHTML = `
-
-
Hiba történt
-
Az üzenet betöltése sikertelen.
-
-
- `;
+ const modalBody = modalContent.querySelector('.modal-body');
+ helper.clearElement(modalBody);
+
+ const errorContent = document.createElement('div');
+ errorContent.className = 'error-content';
+ const errorTitle = document.createElement('h3');
+ errorTitle.textContent = 'Hiba történt';
+ const errorText = document.createElement('p');
+ errorText.textContent = 'Az üzenet betöltése sikertelen.';
+ const retryBtn = document.createElement('button');
+ retryBtn.className = 'retry-btn';
+ retryBtn.textContent = 'Újrapróbálás';
+ retryBtn.onclick = () => openMessageModal(messageId);
+
+ errorContent.appendChild(errorTitle);
+ errorContent.appendChild(errorText);
+ errorContent.appendChild(retryBtn);
+ modalBody.appendChild(errorContent);
}
}
}
@@ -231,38 +256,86 @@
const subject = message.targy || 'Nincs tárgy';
const content = message.szoveg || 'Nincs tartalom';
- modalContent.querySelector('.modal-body').innerHTML = `
-
-
-
- Feladó:
- ${sanitizeHTML(sender)}
-
-
- Dátum:
- ${date}
-
-
- Tárgy:
- ${sanitizeHTML(subject)}
-
-
-
-
Üzenet tartalma:
-
${content}
-
- ${message.csatolmanyok && message.csatolmanyok.length > 0 ? `
-
- ` : ''}
-
- `;
+ const modalBody = modalContent.querySelector('.modal-body');
+ helper.clearElement(modalBody);
+
+ const messageDetails = document.createElement('div');
+ messageDetails.className = 'message-details';
+
+ const messageInfo = document.createElement('div');
+ messageInfo.className = 'message-info';
+
+ const senderRow = document.createElement('div');
+ senderRow.className = 'info-row';
+ const senderLabel = document.createElement('span');
+ senderLabel.className = 'info-label';
+ senderLabel.textContent = 'Feladó:';
+ const senderValue = document.createElement('span');
+ senderValue.className = 'info-value';
+ senderValue.textContent = sanitizeHTML(sender);
+ senderRow.appendChild(senderLabel);
+ senderRow.appendChild(senderValue);
+ messageInfo.appendChild(senderRow);
+
+ const dateRow = document.createElement('div');
+ dateRow.className = 'info-row';
+ const dateLabel = document.createElement('span');
+ dateLabel.className = 'info-label';
+ dateLabel.textContent = 'Dátum:';
+ const dateValue = document.createElement('span');
+ dateValue.className = 'info-value';
+ dateValue.textContent = date;
+ dateRow.appendChild(dateLabel);
+ dateRow.appendChild(dateValue);
+ messageInfo.appendChild(dateRow);
+
+ const subjectRow = document.createElement('div');
+ subjectRow.className = 'info-row';
+ const subjectLabel = document.createElement('span');
+ subjectLabel.className = 'info-label';
+ subjectLabel.textContent = 'Tárgy:';
+ const subjectValue = document.createElement('span');
+ subjectValue.className = 'info-value';
+ subjectValue.textContent = sanitizeHTML(subject);
+ subjectRow.appendChild(subjectLabel);
+ subjectRow.appendChild(subjectValue);
+ messageInfo.appendChild(subjectRow);
+
+ messageDetails.appendChild(messageInfo);
+
+ const messageContent = document.createElement('div');
+ messageContent.className = 'message-content';
+ const contentTitle = document.createElement('h4');
+ contentTitle.textContent = 'Üzenet tartalma:';
+ messageContent.appendChild(contentTitle);
+ const messageText = document.createElement('div');
+ messageText.className = 'message-text';
+ messageText.textContent = content;
+ messageContent.appendChild(messageText);
+ messageDetails.appendChild(messageContent);
+
+ if (message.csatolmanyok && message.csatolmanyok.length > 0) {
+ const messageAttachments = document.createElement('div');
+ messageAttachments.className = 'message-attachments';
+ const attachTitle = document.createElement('h4');
+ attachTitle.textContent = 'Mellékletek:';
+ messageAttachments.appendChild(attachTitle);
+
+ const attachList = document.createElement('ul');
+ message.csatolmanyok.forEach(attachment => {
+ const li = document.createElement('li');
+ const a = document.createElement('a');
+ a.href = '#';
+ a.textContent = sanitizeHTML(attachment.nev);
+ a.onclick = () => downloadAttachment(attachment.azonosito);
+ li.appendChild(a);
+ attachList.appendChild(li);
+ });
+ messageAttachments.appendChild(attachList);
+ messageDetails.appendChild(messageAttachments);
+ }
+
+ modalBody.appendChild(messageDetails);
}
function closeMessageModal() {
@@ -278,41 +351,58 @@
function createLoadingState() {
const loadingDiv = document.createElement('div');
loadingDiv.className = 'loading-state';
- loadingDiv.innerHTML = `
-
-
-
${LanguageManager.t('messages.loading', 'Üzenetek betöltése...')}
-
- `;
+
+ const loadingContent = document.createElement('div');
+ loadingContent.className = 'loading-content';
+ const spinner = document.createElement('div');
+ spinner.className = 'loading-spinner';
+ const text = document.createElement('p');
+ text.textContent = LanguageManager.t('messages.loading', 'Üzenetek betöltése...');
+ loadingContent.appendChild(spinner);
+ loadingContent.appendChild(text);
+ loadingDiv.appendChild(loadingContent);
+
return loadingDiv;
}
function createErrorState(onRetry) {
const errorDiv = document.createElement('div');
errorDiv.className = 'error-state';
- errorDiv.innerHTML = `
-
-
${LanguageManager.t('messages.error.title', 'Hiba történt')}
-
${LanguageManager.t('messages.error.description', 'Az üzenetek betöltése sikertelen volt.')}
-
-
- `;
- const retryBtn = errorDiv.querySelector('.retry-btn');
+ const errorContent = document.createElement('div');
+ errorContent.className = 'error-content';
+ const title = document.createElement('h3');
+ title.textContent = LanguageManager.t('messages.error.title', 'Hiba történt');
+ const desc = document.createElement('p');
+ desc.textContent = LanguageManager.t('messages.error.description', 'Az üzenetek betöltése sikertelen volt.');
+ const retryBtn = document.createElement('button');
+ retryBtn.className = 'retry-btn';
+ retryBtn.textContent = LanguageManager.t('messages.error.retry', 'Újrapróbálás');
retryBtn.addEventListener('click', onRetry);
+ errorContent.appendChild(title);
+ errorContent.appendChild(desc);
+ errorContent.appendChild(retryBtn);
+ errorDiv.appendChild(errorContent);
+
return errorDiv;
}
function createEmptyState() {
const emptyDiv = document.createElement('div');
emptyDiv.className = 'empty-state';
- emptyDiv.innerHTML = `
-
-
${LanguageManager.t('messages.empty.title', 'Nincsenek üzenetek')}
-
${LanguageManager.t('messages.empty.description', 'Jelenleg nincsenek elérhető üzenetek.')}
-
- `;
+
+ const emptyContent = document.createElement('div');
+ emptyContent.className = 'empty-content';
+ const title = document.createElement('h3');
+ title.textContent = LanguageManager.t('messages.empty.title', 'Nincsenek üzenetek');
+ const desc = document.createElement('p');
+ desc.textContent = LanguageManager.t('messages.empty.description', 'Jelenleg nincsenek elérhető üzenetek.');
+
+ emptyContent.appendChild(title);
+ emptyContent.appendChild(desc);
+ emptyDiv.appendChild(emptyContent);
+
return emptyDiv;
}
@@ -332,18 +422,42 @@
const subject = message.uzenetTargy || 'Nincs tárgy';
const date = formatDate(message.uzenetKuldesDatum);
const hasAttachment = message.hasCsatolmany;
+
+ const cardHeader = document.createElement('div');
+ cardHeader.className = 'message-card-header';
- card.innerHTML = `
-
- ${sanitizeHTML(subject)}
- ${hasAttachment ? '📎
' : ''}
- `;
+ const senderInfo = document.createElement('div');
+ senderInfo.className = 'sender-info';
+ const senderNameSpan = document.createElement('span');
+ senderNameSpan.className = 'sender-name';
+ senderNameSpan.textContent = sanitizeHTML(senderName);
+ senderInfo.appendChild(senderNameSpan);
+
+ if (!message.isElolvasva) {
+ const unreadIndicator = document.createElement('span');
+ unreadIndicator.className = 'unread-indicator';
+ senderInfo.appendChild(unreadIndicator);
+ }
+
+ const messageDate = document.createElement('div');
+ messageDate.className = 'message-date';
+ messageDate.textContent = date;
+
+ cardHeader.appendChild(senderInfo);
+ cardHeader.appendChild(messageDate);
+ card.appendChild(cardHeader);
+
+ const messageSubject = document.createElement('div');
+ messageSubject.className = 'message-subject';
+ messageSubject.textContent = sanitizeHTML(subject);
+ card.appendChild(messageSubject);
+
+ if (hasAttachment) {
+ const attachmentIndicator = document.createElement('div');
+ attachmentIndicator.className = 'attachment-indicator';
+ attachmentIndicator.textContent = '📎';
+ card.appendChild(attachmentIndicator);
+ }
return card;
@@ -397,41 +511,111 @@
function renderBulkActions(container) {
const bulk = document.createElement('div');
bulk.className = 'bulk-actions-card';
- bulk.innerHTML = `
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- `;
+
+ const bulkActionsLeft = document.createElement('div');
+ bulkActionsLeft.className = 'bulk-actions-left';
+
+ const viewToggle = document.createElement('div');
+ viewToggle.className = 'view-toggle';
+
+ const viewInboxBtn = document.createElement('button');
+ viewInboxBtn.id = 'viewInboxBtn';
+ viewInboxBtn.className = currentView === 'inbox' ? 'active' : '';
+ viewInboxBtn.title = 'Beérkezett';
+ const inboxImg = document.createElement('img');
+ inboxImg.src = chrome.runtime.getURL('icons/messages-active.svg');
+ inboxImg.alt = 'Beérkezett';
+ viewInboxBtn.appendChild(inboxImg);
+
+ const viewTrashBtn = document.createElement('button');
+ viewTrashBtn.id = 'viewTrashBtn';
+ viewTrashBtn.className = currentView === 'trash' ? 'active' : '';
+ viewTrashBtn.title = 'Törölt';
+ const trashImg = document.createElement('img');
+ trashImg.src = chrome.runtime.getURL('icons/delete.svg');
+ trashImg.alt = 'Törölt';
+ viewTrashBtn.appendChild(trashImg);
+
+ viewToggle.appendChild(viewInboxBtn);
+ viewToggle.appendChild(viewTrashBtn);
+ bulkActionsLeft.appendChild(viewToggle);
+
+ const toggleSelBtn = document.createElement('button');
+ toggleSelBtn.id = 'toggleSelectionModeBtn';
+ toggleSelBtn.className = 'bulk-btn';
+ toggleSelBtn.title = 'Kijelölés mód';
+ const selectImg = document.createElement('img');
+ selectImg.src = chrome.runtime.getURL('icons/select.svg');
+ selectImg.alt = 'Kijelölés mód';
+ toggleSelBtn.appendChild(selectImg);
+ bulkActionsLeft.appendChild(toggleSelBtn);
+
+ const selectAllBtn = document.createElement('button');
+ selectAllBtn.id = 'selectAllBtn';
+ selectAllBtn.className = 'bulk-btn';
+ selectAllBtn.title = 'Mind kijelöl';
+ const selectAllImg = document.createElement('img');
+ selectAllImg.src = chrome.runtime.getURL('icons/select-all.svg');
+ selectAllImg.alt = 'Mind kijelöl';
+ selectAllBtn.appendChild(selectAllImg);
+ bulkActionsLeft.appendChild(selectAllBtn);
+
+ const clearSelBtn = document.createElement('button');
+ clearSelBtn.id = 'clearSelectionBtn';
+ clearSelBtn.className = 'bulk-btn';
+ clearSelBtn.title = 'Kijelölés törlése';
+ const clearSelImg = document.createElement('img');
+ clearSelImg.src = chrome.runtime.getURL('icons/select-none.svg');
+ clearSelImg.alt = 'Kijelölés törlése';
+ clearSelBtn.appendChild(clearSelImg);
+ bulkActionsLeft.appendChild(clearSelBtn);
+
+ bulk.appendChild(bulkActionsLeft);
+
+ const bulkActionsRight = document.createElement('div');
+ bulkActionsRight.className = 'bulk-actions-right';
+
+ const markReadBtn = document.createElement('button');
+ markReadBtn.id = 'markReadBtn';
+ markReadBtn.className = 'bulk-btn';
+ markReadBtn.title = 'Olvasott';
+ const markReadImg = document.createElement('img');
+ markReadImg.src = chrome.runtime.getURL('icons/eye-on.svg');
+ markReadImg.alt = 'Olvasott';
+ markReadBtn.appendChild(markReadImg);
+ bulkActionsRight.appendChild(markReadBtn);
+
+ const markUnreadBtn = document.createElement('button');
+ markUnreadBtn.id = 'markUnreadBtn';
+ markUnreadBtn.className = 'bulk-btn';
+ markUnreadBtn.title = 'Olvasatlan';
+ const markUnreadImg = document.createElement('img');
+ markUnreadImg.src = chrome.runtime.getURL('icons/eye-off.svg');
+ markUnreadImg.alt = 'Olvasatlan';
+ markUnreadBtn.appendChild(markUnreadImg);
+ bulkActionsRight.appendChild(markUnreadBtn);
+
+ const deleteBtn = document.createElement('button');
+ deleteBtn.id = 'deleteBtn';
+ deleteBtn.className = 'bulk-btn';
+ deleteBtn.title = 'Törlés';
+ const deleteImg = document.createElement('img');
+ deleteImg.src = chrome.runtime.getURL('icons/trash.svg');
+ deleteImg.alt = 'Törlés';
+ deleteBtn.appendChild(deleteImg);
+ bulkActionsRight.appendChild(deleteBtn);
+
+ const restoreBtn = document.createElement('button');
+ restoreBtn.id = 'restoreBtn';
+ restoreBtn.className = 'bulk-btn';
+ restoreBtn.title = 'Visszaállítás';
+ const restoreImg = document.createElement('img');
+ restoreImg.src = chrome.runtime.getURL('icons/undo.svg');
+ restoreImg.alt = 'Visszaállítás';
+ restoreBtn.appendChild(restoreImg);
+ bulkActionsRight.appendChild(restoreBtn);
+
+ bulk.appendChild(bulkActionsRight);
container.appendChild(bulk);
bulk.querySelector('#viewInboxBtn').addEventListener('click', () => switchView('inbox'));
@@ -568,13 +752,13 @@ async function switchView(view) {
async function transformMessagesPage() {
try {
await waitForTranslations();
- document.body.innerHTML = '';
+ helper.clearElement(document.body);
const kretaContainer = document.createElement('div');
kretaContainer.className = 'kreta-container';
const headerDiv = document.createElement('div');
- const parser = new DOMParser();
- const headerDoc = parser.parseFromString(await createTemplate.header(), 'text/html');
- const headerContent = headerDoc.body;
+ const template = document.createElement('template');
+ template.innerHTML = await createTemplate.header();
+ const headerContent = template.content;
while (headerContent.firstChild) {
headerDiv.appendChild(headerContent.firstChild);
}
diff --git a/profile/profile.js b/profile/profile.js
index 6a79716..b976e42 100644
--- a/profile/profile.js
+++ b/profile/profile.js
@@ -30,7 +30,7 @@
const backButton = document.createElement('button');
backButton.id = 'firka-back-button';
- backButton.innerHTML = '← Vissza';
+ backButton.textContent = '← Vissza';
backButton.style.cssText = `
position: static;
margin: 20px;
diff --git a/roleselect/roleselect.js b/roleselect/roleselect.js
index 38a6508..2b7f5d3 100644
--- a/roleselect/roleselect.js
+++ b/roleselect/roleselect.js
@@ -154,15 +154,15 @@
if (userName) {
await storageManager.set("userName", userName);
}
- document.body.innerHTML = '';
- const parser = new DOMParser();
- const doc = parser.parseFromString(createHTML(
+ helper.clearElement(document.body);
+ const template = document.createElement('template');
+ template.innerHTML = createHTML(
schoolCode,
fullSchoolName,
userName,
settings,
- ), 'text/html');
- const tempDiv = doc.body;
+ );
+ const tempDiv = template.content;
while (tempDiv.firstChild) {
document.body.appendChild(tempDiv.firstChild);
}
diff --git a/settings/index.js b/settings/index.js
index 4e5fa4b..71347e8 100644
--- a/settings/index.js
+++ b/settings/index.js
@@ -242,19 +242,30 @@ document.addEventListener("DOMContentLoaded", async () => {
const settings = pageSettings[pageType] || [];
if (settings.length === 0) {
- container.innerHTML = `
-
-
settings_suggest
-
Ehhez az oldalhoz nincsenek egyéni beállítások.
-
- `;
+ helper.clearElement(container);
+
+ const placeholder = document.createElement('div');
+ placeholder.className = 'no-settings-placeholder';
+ const icon = document.createElement('span');
+ icon.className = 'material-icons-round';
+ icon.textContent = 'settings_suggest';
+ const text = document.createElement('p');
+ text.setAttribute('data-i18n', 'settings.page_settings.no_settings');
+ text.textContent = 'Ehhez az oldalhoz nincsenek egyéni beállítások.';
+ placeholder.appendChild(icon);
+ placeholder.appendChild(text);
+ container.appendChild(placeholder);
+
if (window.LanguageManager) {
window.LanguageManager.loadTranslationsForPage();
}
return;
}
- container.innerHTML = settings.map(setting => renderSettingItem(setting)).join("");
+ const template = document.createElement('template');
+ template.innerHTML = settings.map(setting => renderSettingItem(setting)).join("");
+ helper.clearElement(container);
+ container.appendChild(template.content);
initSettingItems(container);
if (window.LanguageManager) {
@@ -362,14 +373,20 @@ document.addEventListener("DOMContentLoaded", async () => {
if (!grid) return;
if (customThemes.length === 0) {
- grid.innerHTML = `Még nincsenek egyéni témák
`;
+ helper.clearElement(grid);
+ const noThemes = document.createElement('div');
+ noThemes.className = 'no-custom-themes';
+ noThemes.setAttribute('data-i18n', 'settings.custom_themes.no_themes');
+ noThemes.textContent = 'Még nincsenek egyéni témák';
+ grid.appendChild(noThemes);
if (window.LanguageManager) {
window.LanguageManager.loadTranslationsForPage();
}
return;
}
- grid.innerHTML = customThemes.map(theme => `
+ const template = document.createElement('template');
+ template.innerHTML = customThemes.map(theme => `
`).join("");
+
+ helper.clearElement(grid);
+ grid.appendChild(template.content);
grid.querySelectorAll(".custom-theme-option").forEach(btn => {
btn.addEventListener("click", (e) => {
diff --git a/timetable/timetable.js b/timetable/timetable.js
index 4dee498..bb5322a 100644
--- a/timetable/timetable.js
+++ b/timetable/timetable.js
@@ -197,8 +197,9 @@
}
const htmlText = await response.text();
- const parser = new DOMParser();
- const doc = parser.parseFromString(htmlText, 'text/html');
+ const template = document.createElement('template');
+ template.innerHTML = htmlText;
+ const doc = template.content;
const panelBody = doc.querySelector('.panel-body');
const panelFooter = doc.querySelector('.panel-footer');
const teacherInfo = doc.querySelector('.panel-heading');
@@ -887,18 +888,27 @@
detailsDiv.className = 'homework-details';
const contentP = document.createElement('p');
- contentP.innerHTML = `Feladat: ${homeworkDetails.content}`;
+ const contentStrong = document.createElement('strong');
+ contentStrong.textContent = 'Feladat: ';
+ contentP.appendChild(contentStrong);
+ contentP.appendChild(document.createTextNode(homeworkDetails.content));
detailsDiv.appendChild(contentP);
if (homeworkDetails.deadline) {
const deadlineP = document.createElement('p');
- deadlineP.innerHTML = `Határidő: ${homeworkDetails.deadline}`;
+ const deadlineStrong = document.createElement('strong');
+ deadlineStrong.textContent = 'Határidő: ';
+ deadlineP.appendChild(deadlineStrong);
+ deadlineP.appendChild(document.createTextNode(homeworkDetails.deadline));
detailsDiv.appendChild(deadlineP);
}
if (homeworkDetails.teacher) {
const teacherP = document.createElement('p');
- teacherP.innerHTML = `Tanár: ${homeworkDetails.teacher}`;
+ const teacherStrong = document.createElement('strong');
+ teacherStrong.textContent = 'Tanár: ';
+ teacherP.appendChild(teacherStrong);
+ teacherP.appendChild(document.createTextNode(homeworkDetails.teacher));
detailsDiv.appendChild(teacherP);
}
@@ -908,7 +918,9 @@
attachmentsDiv.style.marginTop = '1rem';
const attachmentsTitle = document.createElement('p');
- attachmentsTitle.innerHTML = 'Csatolmányok:';
+ const attachStrong = document.createElement('strong');
+ attachStrong.textContent = 'Csatolmányok:';
+ attachmentsTitle.appendChild(attachStrong);
attachmentsTitle.style.marginBottom = '0.5rem';
attachmentsDiv.appendChild(attachmentsTitle);
@@ -1213,15 +1225,24 @@
detailsDiv.className = 'test-details';
const nameP = document.createElement('p');
- nameP.innerHTML = `Megnevezés: ${testDetails.name}`;
+ const nameStrong = document.createElement('strong');
+ nameStrong.textContent = 'Megnevezés: ';
+ nameP.appendChild(nameStrong);
+ nameP.appendChild(document.createTextNode(testDetails.name));
detailsDiv.appendChild(nameP);
const typeP = document.createElement('p');
- typeP.innerHTML = `Típus: ${testDetails.type}`;
+ const typeStrong = document.createElement('strong');
+ typeStrong.textContent = 'Típus: ';
+ typeP.appendChild(typeStrong);
+ typeP.appendChild(document.createTextNode(testDetails.type));
detailsDiv.appendChild(typeP);
const dateP = document.createElement('p');
- dateP.innerHTML = `Bejelentés dátuma: ${testDetails.announceDate}`;
+ const dateStrong = document.createElement('strong');
+ dateStrong.textContent = 'Bejelentés dátuma: ';
+ dateP.appendChild(dateStrong);
+ dateP.appendChild(document.createTextNode(testDetails.announceDate));
detailsDiv.appendChild(dateP);
testContent.appendChild(detailsDiv);
@@ -1632,7 +1653,7 @@
modalContent.appendChild(header);
modalContent.appendChild(body);
- modal.innerHTML = '';
+ helper.clearElement(modal);
modal.appendChild(modalContent);
document.body.appendChild(modal);
@@ -1703,11 +1724,11 @@
if (timetableGrid) {
const newContent = await generateTimeGrid(allLessons, weekDates);
- timetableGrid.innerHTML = '';
+ helper.clearElement(timetableGrid);
- const parser1 = new DOMParser();
- const doc = parser1.parseFromString(`${newContent}
`, 'text/html');
- const tempDiv = doc.querySelector('div');
+ const template = document.createElement('template');
+ template.innerHTML = `${newContent}
`;
+ const tempDiv = template.content.querySelector('div');
while (tempDiv.firstChild) {
timetableGrid.appendChild(tempDiv.firstChild);
}
@@ -2186,7 +2207,7 @@
}
- modalGrid.innerHTML = '';
+ helper.clearElement(modalGrid);
allWeeks.forEach((week) => {
const weekCell = document.createElement('div');
weekCell.className = `week-cell ${week.selected ? 'selected' : ''} ${week.selected ? 'current-week' : ''}`;
@@ -2274,7 +2295,7 @@
const weekGrid = document.getElementById("week-grid");
if (weekGrid) {
- weekGrid.innerHTML = '';
+ helper.clearElement(weekGrid);
newWeekOptions.forEach((opt) => {
const weekCell = document.createElement('div');
weekCell.className = `week-cell ${opt.selected ? 'selected' : ''}`;
@@ -2321,7 +2342,7 @@
};
- document.body.innerHTML = '';
+ helper.clearElement(document.body);
const kretaContainer = document.createElement('div');
@@ -2330,9 +2351,9 @@
const headerDiv = document.createElement('div');
- const parser2 = new DOMParser();
- const headerDoc = parser2.parseFromString(await createTemplate.header(), 'text/html');
- const headerContent = headerDoc.body;
+ const template = document.createElement('template');
+ template.innerHTML = await createTemplate.header();
+ const headerContent = template.content;
while (headerContent.firstChild) {
headerDiv.appendChild(headerContent.firstChild);
}
@@ -2480,9 +2501,9 @@
const gridContent = await generateTimeGrid(data.lessons, data.weekDates);
- const parser3 = new DOMParser();
- const doc = parser3.parseFromString(`${gridContent}
`, 'text/html');
- const tempDiv = doc.querySelector('div');
+ const template3 = document.createElement('template');
+ template3.innerHTML = `${gridContent}
`;
+ const tempDiv = template3.content.querySelector('div');
while (tempDiv.firstChild) {
timetableGrid.appendChild(tempDiv.firstChild);
}
@@ -2541,7 +2562,7 @@
}
- weekDisplay.innerHTML = '';
+ helper.clearElement(weekDisplay);
visibleWeeks.forEach((weekNum, index) => {
const isSelected = index === 2;
const isCurrent = weekNum === currentWeekNumber;
@@ -2637,12 +2658,12 @@
const timetableContainer = document.querySelector(".timetable-grid");
if (timetableContainer) {
- timetableContainer.innerHTML = '';
+ helper.clearElement(timetableContainer);
const gridContent = await generateTimeGrid(lessons, weekDates);
- const parser2 = new DOMParser();
- const doc = parser2.parseFromString(`${gridContent}
`, 'text/html');
- const tempDiv = doc.querySelector('div');
+ const template2 = document.createElement('template');
+ template2.innerHTML = `${gridContent}
`;
+ const tempDiv = template2.content.querySelector('div');
while (tempDiv.firstChild) {
timetableContainer.appendChild(tempDiv.firstChild);
}
@@ -2670,7 +2691,7 @@
}
- modalGrid.innerHTML = '';
+ helper.clearElement(modalGrid);
allWeeks.forEach((weekNumber) => {
const isSelected = weekNumber === selectedWeekNumber;
const isCurrent = weekNumber === currentWeekNumber;
diff --git a/tools/helper.js b/tools/helper.js
index 2b33dd9..190547d 100644
--- a/tools/helper.js
+++ b/tools/helper.js
@@ -37,4 +37,28 @@ const helper = {
const [hours, minutes] = timeStr.split(":").map(Number);
return hours * 60 + minutes;
},
+
+ createElementFromHTML(htmlString) {
+ const template = document.createElement('template');
+ template.innerHTML = htmlString.trim();
+ return template.content;
+ },
+
+ setTextContent(element, text) {
+ element.textContent = text;
+ },
+
+ clearElement(element) {
+ while (element.firstChild) {
+ element.removeChild(element.firstChild);
+ }
+ },
+
+ appendChildren(parent, children) {
+ if (Array.isArray(children)) {
+ children.forEach(child => parent.appendChild(child));
+ } else {
+ parent.appendChild(children);
+ }
+ }
};
\ No newline at end of file