diff --git a/client/src/routes/Files.svelte b/client/src/routes/Files.svelte index b44b249..9e21fb5 100644 --- a/client/src/routes/Files.svelte +++ b/client/src/routes/Files.svelte @@ -24,6 +24,11 @@ return trimmed; }; + const IS_SAFARI = + typeof navigator !== "undefined" && + /safari/i.test(navigator.userAgent || "") && + !/chrome|crios|android/i.test(navigator.userAgent || ""); + const shouldHideRootSegment = (segment) => segment && (HIDDEN_ROOT_REGEX.test(segment) || segment === "downloads"); @@ -1325,35 +1330,24 @@ (normalizedKey === "a" || e.code === "KeyA" || e.keyCode === 65); if (isSelectAllKey) { - // Text input'larda ve klasör oluşturma modunda çalıştırma if (isEditable || isCreatingFolder) return; - // Safari ve diğer tarayıcılarda default davranışı engelle e.preventDefault(); e.stopPropagation(); - if (typeof e.stopImmediatePropagation === "function") { + if (IS_SAFARI && typeof e.stopImmediatePropagation === "function") { e.stopImmediatePropagation(); } - // Safari için ek güvenlik önlemleri - setTimeout(() => { - if (visibleEntries.length > 0) { - const allKeys = visibleEntries - .map( - (entry) => - entry?.name || - entry?.displayPath || - entry?.primaryOriginalPath || - null, - ) - .filter(Boolean); - if (allKeys.length > 0) { - selectedItems = new Set(allKeys); - if (isCreatingFolder) cancelCreateFolder(); - } - } - }, 0); - + const allKeys = visibleEntries + .map( + (entry) => + entry?.name || entry?.displayPath || entry?.primaryOriginalPath || null, + ) + .filter(Boolean); + if (allKeys.length > 0) { + selectedItems = new Set(allKeys); + if (isCreatingFolder) cancelCreateFolder(); + } return; } if (showModal || showImageModal) { @@ -1361,186 +1355,39 @@ if (e.key === "ArrowLeft") showPrev(); } } - const keyListenerOptions = { capture: true, passive: false }; - const handleKeyUp = (e) => { + const safariListenerOptions = { capture: true, passive: false }; + const keyTargets = IS_SAFARI + ? [window, document, document.body].filter(Boolean) + : [window]; + const keydownOptions = IS_SAFARI ? safariListenerOptions : false; + const preventIfSelectAll = (e) => { + if (!IS_SAFARI) return; const normalizedKey = (e.key || "").toLowerCase(); const isCmd = e.metaKey || e.ctrlKey; const isSelectAllKey = isCmd && (normalizedKey === "a" || e.code === "KeyA" || e.keyCode === 65); - if (isSelectAllKey) { - // Safari için güçlü event engelleme e.preventDefault(); e.stopPropagation(); if (typeof e.stopImmediatePropagation === "function") { e.stopImmediatePropagation(); } - return false; } }; - const handleKeyPress = (e) => { - const normalizedKey = (e.key || "").toLowerCase(); - const isCmd = e.metaKey || e.ctrlKey; - const isSelectAllKey = - isCmd && - (normalizedKey === "a" || e.code === "KeyA" || e.keyCode === 65); - - if (isSelectAllKey) { - // Safari için güçlü event engelleme - e.preventDefault(); - e.stopPropagation(); - if (typeof e.stopImmediatePropagation === "function") { - e.stopImmediatePropagation(); - } - return false; - } - }; - - // Safari için özel keydown handler - const handleSafariKeyDown = (e) => { - const normalizedKey = (e.key || "").toLowerCase(); - const isCmd = e.metaKey || e.ctrlKey; - const isSelectAllKey = - isCmd && - (normalizedKey === "a" || e.code === "KeyA" || e.keyCode === 65); - - if (isSelectAllKey) { - const active = document.activeElement; - const tag = active?.tagName; - const type = active?.type?.toLowerCase(); - const isTextInput = - tag === "INPUT" && - [ - "text", - "search", - "email", - "password", - "number", - "url", - "tel", - ].includes(type); - const isEditable = - (tag === "TEXTAREA" || isTextInput || active?.isContentEditable) ?? - false; - // Text input'larda ve klasör oluşturma modunda çalıştırma - if (isEditable || isCreatingFolder) return; - - // Safari için maksimum event kontrolü - e.preventDefault(); - e.stopPropagation(); - if (typeof e.stopImmediatePropagation === "function") { - e.stopImmediatePropagation(); - } - - // Async execution for Safari compatibility - setTimeout(() => { - if (visibleEntries.length > 0) { - const allKeys = visibleEntries - .map( - (entry) => - entry?.name || - entry?.displayPath || - entry?.primaryOriginalPath || - null, - ) - .filter(Boolean); - if (allKeys.length > 0) { - selectedItems = new Set(allKeys); - if (isCreatingFolder) cancelCreateFolder(); - } - } - }, 0); - - return false; - } - }; - - // Safari detection - const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); - const keyTargets = [window, document, document.body].filter(Boolean); - - // Normal event listeners (tüm tarayıcılar için) keyTargets.forEach((target) => - target.addEventListener("keydown", handleKey, keyListenerOptions), + target.addEventListener("keydown", handleKey, keydownOptions), ); - keyTargets.forEach((target) => - target.addEventListener("keyup", handleKeyUp, keyListenerOptions), - ); - keyTargets.forEach((target) => - target.addEventListener("keypress", handleKeyPress, keyListenerOptions), - ); - - // Safari için ek event listeners - if (isSafari) { + if (IS_SAFARI) { keyTargets.forEach((target) => - target.addEventListener("keydown", handleSafariKeyDown, { capture: true }), + target.addEventListener("keyup", preventIfSelectAll, safariListenerOptions), + ); + keyTargets.forEach((target) => + target.addEventListener("keypress", preventIfSelectAll, safariListenerOptions), ); - - // Safari'de document-level keydown için ek listener - document.addEventListener("keydown", handleSafariKeyDown, { - capture: true, - passive: false - }); - - // Safari için window-level global handler - window.addEventListener("keydown", (e) => { - const normalizedKey = (e.key || "").toLowerCase(); - const isCmd = e.metaKey || e.ctrlKey; - const isSelectAllKey = - isCmd && - (normalizedKey === "a" || e.code === "KeyA" || e.keyCode === 65); - - if (isSelectAllKey) { - e.preventDefault(); - e.stopPropagation(); - if (typeof e.stopImmediatePropagation === "function") { - e.stopImmediatePropagation(); - } - - // Maksimum uyumluluk için gecikme - setTimeout(() => { - const active = document.activeElement; - const tag = active?.tagName; - const type = active?.type?.toLowerCase(); - const isTextInput = - tag === "INPUT" && - [ - "text", - "search", - "email", - "password", - "number", - "url", - "tel", - ].includes(type); - const isEditable = - (tag === "TEXTAREA" || isTextInput || active?.isContentEditable) ?? - false; - - if (!isEditable && !isCreatingFolder && visibleEntries.length > 0) { - const allKeys = visibleEntries - .map( - (entry) => - entry?.name || - entry?.displayPath || - entry?.primaryOriginalPath || - null, - ) - .filter(Boolean); - if (allKeys.length > 0) { - selectedItems = new Set(allKeys); - if (isCreatingFolder) cancelCreateFolder(); - } - } - }, 10); - - return false; - } - }, { capture: true, passive: false }); } - + window.addEventListener("popstate", handlePopState); // Menüyü kapatmak için dışarı tıklama olayı @@ -1553,32 +1400,18 @@ window.addEventListener("click", handleClickOutside); return () => { - // Normal event listeners temizliği keyTargets.forEach((target) => - target.removeEventListener("keydown", handleKey, keyListenerOptions), + target.removeEventListener("keydown", handleKey, keydownOptions), ); - keyTargets.forEach((target) => - target.removeEventListener("keyup", handleKeyUp, keyListenerOptions), - ); - keyTargets.forEach((target) => - target.removeEventListener("keypress", handleKeyPress, keyListenerOptions), - ); - - // Safari için ek event listeners temizliği - if (isSafari) { + if (IS_SAFARI) { keyTargets.forEach((target) => - target.removeEventListener("keydown", handleSafariKeyDown, { capture: true }), + target.removeEventListener("keyup", preventIfSelectAll, safariListenerOptions), + ); + keyTargets.forEach((target) => + target.removeEventListener("keypress", preventIfSelectAll, safariListenerOptions), ); - - document.removeEventListener("keydown", handleSafariKeyDown, { - capture: true, - passive: false - }); - - // Safari global window handler temizliği - window.removeEventListener("keydown", () => {}, { capture: true }); } - + window.removeEventListener("click", handleClickOutside); window.removeEventListener("popstate", handlePopState); try {