kontextmenü bug entfernt

This commit is contained in:
2026-10-08 12:51:44 +02:00
parent b108779b2b
commit 8a468d0f7c
+53 -14
View File
@@ -1,7 +1,7 @@
// ==UserScript== // ==UserScript==
// @name academyFIVE::HighlightStudyRow // @name academyFIVE::HighlightStudyRow
// @namespace dakp/academyfive // @namespace dakp/academyfive
// @version 2026.10.003 // @version 2026.10.004
// @description Hebt beim Hovern einer Zelle die gesamte <tr>-Zeile der Studiensemester-Tabelle (profil_studenten_edit.php4) per CSS hervor // @description Hebt beim Hovern einer Zelle die gesamte <tr>-Zeile der Studiensemester-Tabelle (profil_studenten_edit.php4) per CSS hervor
// @author Dims Akpan // @author Dims Akpan
// @match https://a5.fhdw-hannover.de/admin/* // @match https://a5.fhdw-hannover.de/admin/*
@@ -15,27 +15,48 @@
(function() { (function() {
'use strict'; 'use strict';
const STYLE_CLASS = 'a5-row-hl';
const HOVER_COLOR = 'rgba(0, 120, 200, 0.12)'; const HOVER_COLOR = 'rgba(0, 120, 200, 0.12)';
const STUDY_INPUTS = 'input[name*="hochschulsemester"], input[name*="fachsemester"], input[name*="as_gesamt"]';
// Reines CSS: Hover wird nativ vom Browser verfolgt function injectStyle(css) {
const style = document.createElement('style'); const style = document.createElement('style');
style.textContent = ` style.textContent = css;
(document.head || document.documentElement).appendChild(style);
}
// Bevorzugter Pfad: reines CSS über :has(). Kein JavaScript, kein Observer,
// keine DOM-Änderungen -> das Script kann Eigenheiten der Seite (z.B.
// Kontextmenüs, die auf DOM-Änderungen/Mausbewegung reagieren) nicht stören.
const HAS_TABLE = `table:has(${STUDY_INPUTS})`;
const cssSupportsHas = typeof CSS !== 'undefined'
&& typeof CSS.supports === 'function'
&& CSS.supports(`selector(${HAS_TABLE})`);
if (cssSupportsHas) {
injectStyle(`
${HAS_TABLE} tr:hover th,
${HAS_TABLE} tr:hover td {
background-color: ${HOVER_COLOR} !important;
}
`);
return;
}
// Fallback für ältere Browser ohne :has()-Unterstützung:
const STYLE_CLASS = 'a5-row-hl';
injectStyle(`
table.${STYLE_CLASS} tr:hover th, table.${STYLE_CLASS} tr:hover th,
table.${STYLE_CLASS} tr:hover td { table.${STYLE_CLASS} tr:hover td {
background-color: ${HOVER_COLOR} !important; background-color: ${HOVER_COLOR} !important;
} }
`; `);
(document.head || document.documentElement).appendChild(style);
// Studiensemester-Tabelle anhand typischer Eingabefelder erkennen
function isStudyTable(table) { function isStudyTable(table) {
return !!table.querySelector('input[name*="hochschulsemester"], input[name*="fachsemester"], input[name*="as_gesamt"]'); return !!table.querySelector(STUDY_INPUTS);
} }
function markTable(table) { function markTable(table) {
if (table.dataset.a5RowHl || table.classList.contains(STYLE_CLASS)) return; if (table.classList.contains(STYLE_CLASS)) return;
table.dataset.a5RowHl = 'true';
table.classList.add(STYLE_CLASS); table.classList.add(STYLE_CLASS);
} }
@@ -45,12 +66,30 @@
}); });
} }
// Entprellter Observer, der nur auf neu eingefügte Tabellen/Inputs reagiert
// und nicht auf jede beliebige DOM-Änderung (Kontextmenü, Tooltips, Hover-Klassen).
let scanScheduled = false;
function scheduleScan() {
if (scanScheduled) return;
scanScheduled = true;
setTimeout(() => {
scanScheduled = false;
scanTables();
}, 200);
}
function onDocReady() { function onDocReady() {
scanTables(); scanTables();
// Für dynamisch nachgeladene Tabellen: Klassenzuweisung ist idempotent, new MutationObserver(mutations => {
// daher dünner Observer mit kindList/childList. const relevant = mutations.some(m =>
new MutationObserver(scanTables) Array.from(m.addedNodes).some(n =>
.observe(document.documentElement, { childList: true, subtree: true }); n.nodeType === Node.ELEMENT_NODE &&
(n.tagName === 'TABLE' || n.tagName === 'INPUT' ||
n.querySelector('table') || n.querySelector('input'))
)
);
if (relevant) scheduleScan();
}).observe(document.documentElement, { childList: true, subtree: true });
} }
if (document.readyState === 'loading') { if (document.readyState === 'loading') {