Hi
Sören Hentzschel
Das beobachte Verhalten ist wirklich nicht nice.
In dieser Version prüfe ich ob die Maus das Fenster verläßt oder von außen ins Fenster kommt.
"Fliegt" die Maus ins Fenster (<50ms im Triggerbereich) öffnet die Sidebar nicht.
Wird die Maus aus dem Fenster bewegt öffnet die Sidebar auch nicht. Ist die Sidebar bereits offen so schließt sie sich.
JavaScript: Juras-SidebarV1.3.uc.js
// Author: Juras & KI
// Version: 1.3
// Changelog: 02.01.2026 Verhindert das Öffnen der Sidebar wenn die Maus aus dem Fenster raus/rein bewegt wird.
// 01.01.2026 Variable zum Verzögern des Aufklappens der Sidebar hinzugefügt
// Sidebar wird nur dargestellt wenn im FF eingeschaltet
// 22.12.2025 Sensorbereich auf den Content-Bereich begrenzt (beginnt unterhalb der Toolbox (Symbolleisten/Tabs))
// 21.12.2025 Sidebar wird per mouse hover im sensorbereich am Rand getriggert (einstellbar)
// Umschaltbar für links und rechts
// Bleibt offen bei Auswahl im Sidebar Menü
// Sidebar Breite via Maus einstellbar (initiale Breite konfigurierbar)
// Sidebar Hintergrundfarbe stellt sich automatisch in Abhängigkeit von Theme (hell/dunkel) ein
// Transparenz des Sidebar Hintergrundes einstellbar
//
(function() {
if (window.jsSidebarActive) return;
window.jsSidebarActive = true;
// --- KONFIGURATION ---
const MIN_TRIGGER_WIDTH = 15;
const OPEN_DELAY = 1500;
const CLOSE_DELAY = 600;
let currentWidth = 310;
const BG_TRANSPARENCY = 0.92;
const sidebar = document.getElementById("sidebar-box");
const toolbox = document.getElementById("navigator-toolbox");
const browser = document.getElementById("browser");
const appContent = document.getElementById("appcontent");
if (!sidebar || !toolbox || !browser) return;
let isMenuOpen = false;
let isMouseInSidebar = false;
let isResizing = false;
let cachedTopOffset = 0;
let openTimer = null;
let closeTimer = null;
// NEU: Zeitstempel, um "Einfliegen" von außerhalb zu erkennen
let lastWindowEntryTime = 0;
function isSidebarEnabled() {
return !sidebar.hasAttribute("hidden") && sidebar.getAttribute("closed") !== "true";
}
function isSidebarRight() {
try {
if (sidebar.getAttribute("positionend") === "true") return true;
return !Services.prefs.getBoolPref("sidebar.position_start", true);
} catch (e) { return false; }
}
const style = document.createElement("style");
style.id = "sidebar-hover-style";
document.head.appendChild(style);
function updateStyles() {
if (!isSidebarEnabled()) {
style.textContent = "";
sidebar.removeAttribute("visible");
return;
}
const isRight = isSidebarRight();
const topOffset = toolbox.getBoundingClientRect().height;
if (topOffset === 0) return;
cachedTopOffset = topOffset;
sidebar.setAttribute("data-side", isRight ? "right" : "left");
style.textContent = `
#sidebar-box {
position: fixed !important;
z-index: 10000 !important;
top: ${topOffset}px !important;
height: calc(100vh - ${topOffset}px) !important;
width: var(--hover-sidebar-width, ${currentWidth}px) !important;
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
background-color: light-dark(rgba(255, 255, 255, ${BG_TRANSPARENCY}), rgba(28, 28, 30, ${BG_TRANSPARENCY})) !important;
backdrop-filter: blur(15px) saturate(140%);
border: none !important;
display: flex !important;
}
#sidebar-box[data-side="left"] { left: 0 !important; right: auto !important; border-right: 1px solid var(--chrome-content-separator-color) !important; }
#sidebar-box[data-side="left"]:not([visible="true"]) { transform: translateX(-100%) !important; }
#sidebar-box[data-side="right"] { right: 0 !important; left: auto !important; border-left: 1px solid var(--chrome-content-separator-color) !important; }
#sidebar-box[data-side="right"]:not([visible="true"]) { transform: translateX(100%) !important; }
#sidebar-box[visible="true"] { transform: translateX(0) !important; }
#sidebar-resizer-grip {
position: absolute; top: 0; width: 16px; height: 100%;
cursor: ew-resize !important; z-index: 10001; background: transparent;
}
#sidebar-box[data-side="left"] #sidebar-resizer-grip { right: -8px; }
#sidebar-box[data-side="right"] #sidebar-resizer-grip { left: -8px; }
#sidebar-box[resizing="true"]::after {
content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0;
z-index: 99999; background: transparent;
}
#sidebar-box:not([visible="true"]) { pointer-events: none !important; }
#sidebar-splitter { display: none !important; }
#sidebar-header { background-color: transparent !important; }
`;
}
const sidebarObserver = new MutationObserver(() => updateStyles());
sidebarObserver.observe(sidebar, { attributes: true, attributeFilter: ['positionend', 'hidden', 'closed'] });
sidebarObserver.observe(browser, { attributes: true, subtree: true, attributeFilter: ['positionend'] });
Services.prefs.addObserver("sidebar.position_start", updateStyles);
window.addEventListener("resize", updateStyles);
setTimeout(updateStyles, 200);
// --- LOGIK: FENSTER-FOKUS & EINTRITT ---
window.addEventListener("mouseenter", () => {
lastWindowEntryTime = Date.now();
}, true);
window.addEventListener("mouseleave", () => {
if (openTimer) {
clearTimeout(openTimer);
openTimer = null;
}
}, true);
window.addEventListener("popupshown", (e) => {
if (e.target.id === "sidebarMenu-popup" || e.target.getAttribute("viewid")?.startsWith("sidebar-")) isMenuOpen = true;
}, true);
window.addEventListener("popuphidden", (e) => {
if (e.target.id === "sidebarMenu-popup" || e.target.getAttribute("viewid")?.startsWith("sidebar-")) {
isMenuOpen = false;
if (!isMouseInSidebar) startCloseTimer();
}
}, true);
function startCloseTimer() {
if (closeTimer) clearTimeout(closeTimer);
closeTimer = setTimeout(() => {
if (!isMouseInSidebar && !isMenuOpen && !isResizing) {
sidebar.setAttribute("visible", "false");
}
closeTimer = null;
}, CLOSE_DELAY);
}
// --- LOGIK: ÖFFNEN ---
window.addEventListener("mousemove", (e) => {
if (isResizing || !isSidebarEnabled()) return;
const isRight = isSidebarRight();
const winWidth = window.innerWidth;
// Prüfung 1: Ist die Maus im horizontalen Trigger-Bereich?
const inHorizontalTrigger = isRight ? (e.clientX >= winWidth - MIN_TRIGGER_WIDTH) : (e.clientX <= MIN_TRIGGER_WIDTH);
// Prüfung 2: Ist die Maus unterhalb der Toolbars?
const inVerticalTrigger = (e.clientY >= cachedTopOffset);
if (inHorizontalTrigger && inVerticalTrigger) {
// VERHINDERUNG: Wenn die Maus gerade erst das Fenster betreten hat (weniger als 50ms her),
// ignorieren wir den ersten Trigger, um Öffnen beim Monitorwechsel zu vermeiden.
if (Date.now() - lastWindowEntryTime < 50) return;
if (closeTimer) { clearTimeout(closeTimer); closeTimer = null; }
if (sidebar.getAttribute("visible") !== "true" && !openTimer) {
openTimer = setTimeout(() => {
sidebar.setAttribute("visible", "true");
openTimer = null;
}, OPEN_DELAY);
}
} else {
if (openTimer) {
clearTimeout(openTimer);
openTimer = null;
}
}
}, { passive: true });
sidebar.addEventListener("mouseenter", () => {
if (!isSidebarEnabled()) return;
isMouseInSidebar = true;
if (openTimer) { clearTimeout(openTimer); openTimer = null; }
if (closeTimer) { clearTimeout(closeTimer); closeTimer = null; }
});
sidebar.addEventListener("mouseleave", () => {
isMouseInSidebar = false;
if (!isResizing && sidebar.getAttribute("visible") === "true") startCloseTimer();
});
// --- RESIZE LOGIK ---
const grip = document.createElement("div");
grip.id = "sidebar-resizer-grip";
sidebar.appendChild(grip);
grip.addEventListener("mousedown", (e) => {
if (!isSidebarEnabled()) return;
isResizing = true;
sidebar.setAttribute("resizing", "true");
sidebar.style.transition = "none";
const isRight = isSidebarRight();
const startX = e.clientX;
const startWidth = currentWidth;
const doResize = (me) => {
let diff = me.clientX - startX;
let newWidth = isRight ? (startWidth - diff) : (startWidth + diff);
if (newWidth > 50 && newWidth < window.innerWidth * 0.9) {
currentWidth = newWidth;
sidebar.style.setProperty("--hover-sidebar-width", currentWidth + "px");
}
};
const stopResize = () => {
isResizing = false;
sidebar.removeAttribute("resizing");
sidebar.style.transition = "transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)";
window.removeEventListener("mousemove", doResize, true);
window.removeEventListener("mouseup", stopResize, true);
if (!isMouseInSidebar) startCloseTimer();
};
window.addEventListener("mousemove", doResize, true);
window.addEventListener("mouseup", stopResize, true);
e.preventDefault();
}, true);
window.addEventListener("mousedown", (e) => {
if (!isSidebarEnabled() || sidebar.getAttribute("visible") !== "true" || isMenuOpen || isResizing) return;
if (appContent && appContent.contains(e.target)) {
sidebar.setAttribute("visible", "false");
}
}, true);
})();
Alles anzeigen