22 januari 2026

Belangrijk: darktable herstelt automatisch de sneltoetsen instellingen wanneer het opstart.

Opdat je aangepaste bezetting niet verloren gaat, moet je dit automatische herstel deactiveren.

  • Ga naar darktable voorkeuren > diversen.
  • Schakel de optie uit ‘laad standaard sneltoetsen bij opstarten’ (indien beschikbaar/actief).

Installatie van het bestand:

  • sluit darktable
  • vervang het bestand shortcutrc in je configuratie map met de nieuwe versie.
:root { –key-bg: #f0f0f0; –key-bg-modifier: #e0e0e0; –key-bg-assigned: #007bff; –key-bg-selected: #28a745; –key-border: #ccc; –key-color: #333; –key-color-assigned: #fff; –key-color-selected: #fff; } body { transition: background-color 0.3s, color 0.3s; font-family: -apple-system, BlinkMacSystemFont, “Segoe UI”, Roboto, Helvetica, Arial, sans-serif; } body.drag-over { outline: 3px dashed #3a86ff; outline-offset: -10px; } .keyboard-container { background: #f0f0f0; padding: 15px; border-radius: 8px; margin-bottom: 15px; display: grid; grid-template-areas: “fkeys fkeys fkeys” “main main special” “main main arrows”; grid-template-columns: auto auto auto; gap: 15px; } .keyboard-fkeys { grid-area: fkeys; } .keyboard-main { grid-area: main; } .keyboard-special { grid-area: special; } .keyboard-arrows { grid-area: arrows; } .keyboard-block { display: flex; flex-direction: column; gap: 6px; } .key-row { display: flex; justify-content: flex-start; gap: 6px; } .key { border: 1px solid var(–key-border); background: var(–key-bg); color: var(–key-color); border-radius: 5px; padding: 8px 8px; cursor: pointer; position: relative; transition: all 0.2s; min-width: 35px; height: 33px; display: flex; align-items: center; justify-content: center; font-size: 14px; box-sizing: border-box; } /* KORRIGIERT: z-index beim Hovern hinzufügen */ .key:hover { filter: brightness(95%); z-index: 101; } .key.modifier { background: var(–key-bg-modifier); } .key.assigned { background-color: var(–key-bg-assigned); color: var(–key-color-assigned); border-color: var(–key-bg-assigned); } .key.selected { background-color: var(–key-bg-selected); color: var(–key-color-selected); border-color: var(–key-bg-selected); transform: translateY(1px); } .key .tooltip-text { visibility: hidden; width: max-content; max-width: 550px; background-color: #333; color: #fff; text-align: left; border-radius: 6px; padding: 10px 12px; position: absolute; z-index: 100; /* KORRIGIERT: z-index erhöht */ bottom: 125%; left: 50%; transform: translateX(-50%); opacity: 0; transition: opacity 0.3s; white-space: pre-wrap; font-size: 14px; line-height: 1.4; pointer-events: none; } .key.assigned:hover .tooltip-text { visibility: visible; opacity: 1; } /* Special Key Sizes */ .key-spacer { width: 11px; background: transparent; border: none; } .key-fkey { min-width: 37px; } .key-special { min-width: 60px; } .key-backspace { width: 115px; } .key-tab { width: 67px; } .key-caps { width: 87px; } .key-return { width: 83px; } .key-shift-l { width: 95px; } .key-shift-r { width: 96px; } .key-ctrl { width: 60px; } .key-space { width: 372px; } /* Table adjustments */ .actions-cell { width: 1%; white-space: nowrap; text-align: right; } /* Dark Theme */ body.dark-mode { background-color: #121212; color: #e0e0e0; –key-bg: #444; –key-bg-modifier: #555; –key-bg-assigned: #3a86ff; –key-bg-selected: #20c997; –key-border: #666; –key-color: #e0e0e0; } .dark-mode .card, .dark-mode .keyboard-container { background-color: #1e1e1e; border-color: #333; } .dark-mode .table { color: #e0e0e0; } .dark-mode .table > :not(caption) > * > * { border-bottom-width: 0; } .dark-mode thead th { border-bottom: 1px solid var(–key-border); } .dark-mode .table-striped > tbody > tr:nth-of-type(odd) { background-color: rgba(255, 255, 255, 0.05); } .dark-mode .form-control, .dark-mode .form-select { background-color: #2a2a2a; color: #e0e0e0; border-color: #525252; } .dark-mode .btn-primary { background-color: #3a86ff; border-color: #3a86ff; } .dark-mode .key-spacer { background: transparent !important; } /* Bootstrap replacements */ .container { max-width: 1000px; margin: 0 auto; padding: 0 15px; } .mt-5 { margin-top: 3rem; } .d-flex { display: flex; } .justify-content-between { justify-content: space-between; } .align-items-center { align-items: center; } .mb-4 { margin-bottom: 1.5rem; } .btn { display: inline-block; padding: 0.375rem 0.75rem; font-size: 12px; line-height: 1.5; border-radius: 0.25rem; text-align: center; vertical-align: middle; cursor: pointer; border: 1px solid transparent; text-decoration: none; user-select: none; } .btn-outline-secondary { color: #6c757d; border-color: #6c757d; background-color: transparent; } .btn-outline-secondary:hover { color: #fff; background-color: #6c757d; } .card { position: relative; display: flex; flex-direction: column; min-width: 0; word-wrap: break-word; background-color: #fff; background-clip: border-box; border: 1px solid rgba(0, 0, 0, 0.125); border-radius: 0.25rem; } .card-body { flex: 1 1 auto; padding: 1rem; } .d-none { display: none !important; } .form-control { display: block; width: 95%; padding: 0.375rem 0.75rem; font-size: 14px; font-weight: 400; line-height: 1.5; color: #495057; background-color: #fff; background-clip: padding-box; border: 1px solid #ced4da; appearance: none; border-radius: 0.25rem; transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; } .mt-2 { margin-top: 0.5rem; } .text-muted { color: #6c757d !important; } .mb-3 { margin-bottom: 1rem; } .form-label { margin-bottom: 0.5rem; } .m-0 { margin: 0; } .me-2 { margin-right: 0.5rem; } .form-select { display: block; width: 100%; padding: 0.375rem 2.25rem 0.375rem 0.75rem; font-size: 12px; font-weight: 400; line-height: 1.5; color: #495057; background-color: #fff; background-image: url(“data:image/svg+xml,%3csvg xmlns=’http://www.w3.org/2000/svg’ viewBox=’0 0 16 16′ fill=’%23343a40’%3e%3cpath fill-rule=’evenodd’ d=’M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z’/%3e%3c/svg%3e”); background-repeat: no-repeat; background-position: right 0.75rem center; background-size: 16px 12px; border: 1px solid #ced4da; border-radius: 0.25rem; appearance: none; } .d-inline { display: inline !important; } .w-auto { width: auto !important; } .ms-3 { margin-left: 1rem; } .gap-2 { gap: 0.5rem; } .btn-success { color: #fff; background-color: #28a745; border-color: #28a745; } .btn-success:hover { color: #fff; background-color: #218838; border-color: #1e7e34; } .btn-primary { color: #fff; background-color: #007bff; border-color: #007bff; } .btn-primary:hover { color: #fff; background-color: #0069d9; border-color: #0062cc; } .table { width: 100%; margin-bottom: 1rem; color: #212529; } .table th, .table td { padding: 5px; vertical-align: top; border-top: 0px solid #dee2e4; } .table thead th { vertical-align: bottom; border-bottom: 2px solid #dee2e4; } .table tbody + tbody { border-top: 2px solid #dee2e4; } .table-striped tbody tr:nth-of-type(odd) { background-color: rgba(0, 0, 0, 0.05); } .text-center { text-align: center !important; } .btn-sm { padding: 0.25rem 0.5rem; font-size: 12px; line-height: 1.5; border-radius: 0.2rem; } .btn-warning { color: #212529; background-color: #ffc107; border-color: #ffc107; } .btn-warning:hover { color: #212529; background-color: #e0a800; border-color: #d39e00; } .btn-danger { color: #fff; background-color: #dc3545; border-color: #dc3545; } .btn-danger:hover { color: #fff; background-color: #c82333; border-color: #bd2130; } .btn-secondary { color: #fff; background-color: #6c757d; border-color: #6c757d; } .btn-secondary:hover { color: #fff; background-color: #5a6268; border-color: #545b62; }
QWERTZ QWERTY AZERTY

Load your shortcutsrc file to begin editing. You can also drag & drop the file anywhere on this page.

Default By Key By Value
Shortcut Key Action (Value) Context Actions
const preloadedShortcutsrcContent = “; // — CONFIGURATION — const KEYBOARD_LAYOUTS = { qwertz: { fkeys: [ [ [“Escape”], “SPACER”, [“F1”, “F1”, “key-fkey”], [“F2”, “F2”, “key-fkey”], [“F3”, “F3”, “key-fkey”], [“F4”, “F4”, “key-fkey”], “SPACER”, [“F5”, “F5”, “key-fkey”], [“F6”, “F6”, “key-fkey”], [“F7”, “F7”, “key-fkey”], [“F8”, “F8”, “key-fkey”], “SPACER”, [“F9”, “F9”, “key-fkey”], [“F10”, “F10”, “key-fkey”], [“F11”, “F11”, “key-fkey”], [“F12”, “F12”, “key-fkey”], “SPACER”, ], ], main: [ [ [“^”, “asciicircum”], [“1”], [“2”], [“3”], [“4”], [“5”], [“6”], [“7”], [“8”], [“9”], [“0”], [“ß”, “ssharp”], [“´”, “acute”], [“BackSpace”, “BackSpace”, “key-backspace”], ], [ [“Tab”, “Tab”, “key-tab”, “modifier”], [“q”], [“w”], [“e”], [“r”], [“t”], [“z”], [“u”], [“i”], [“o”], [“p”], [“Ü”, “udiaeresis”], [“+”, “plus”], [“Return”, “Return”, “key-return”], ], [ [“Caps”, “Caps_Lock”, “key-caps”, “modifier”], [“a”], [“s”], [“d”], [“f”], [“g”], [“h”], [“j”], [“k”], [“l”], [“Ö”, “odiaeresis”], [“Ä”, “adiaeresis”], [“#”, “numbersign”], ], [ [“Shift”, “shift”, “key-shift-l”, “modifier”], [“<", "<"], ["y"], ["x"], ["c"], ["v"], ["b"], ["n"], ["m"], [",", "comma"], [".", "period"], ["-", "minus"], ["Shift", "shift", "key-shift-r", "modifier"], ], [ ["Ctrl", "control", "key-ctrl", "modifier"], ["Win", "super", "", "modifier"], ["Alt", "alt", "", "modifier"], ["Space", "space", "key-space"], ["AltGr", "alt", "", "modifier"], ["Ctrl", "control", "key-ctrl", "modifier"], ], ], special: [ [ ["Print", "Print", "key-special"], ["Scroll", "Scroll", "key-special"], ["Pause", "Pause", "key-special"], ["None", "None", "key-special"], ], [ ["Ins", "Insert", "key-special"], ["Home", "Home", "key-special"], ["P_Up", "Page_Up", "key-special"], ], [ ["Delete", "Delete", "key-special"], ["End", "End", "key-special"], ["P_Down", "Page_Down", "key-special"], ], ], arrows: [ [ ["Left", "Left", "key-special"], ["Up", "Up", "key-special"], ["Down", "Down", "key-special"], ["Right", "Right", "key-special"], ], ], }, qwerty: { fkeys: [ [ ["Escape"], "SPACER", ["F1", "F1", "key-fkey"], ["F2", "F2", "key-fkey"], ["F3", "F3", "key-fkey"], ["F4", "F4", "key-fkey"], "SPACER", ["F5", "F5", "key-fkey"], ["F6", "F6", "key-fkey"], ["F7", "F7", "key-fkey"], ["F8", "F8", "key-fkey"], "SPACER", ["F9", "F9", "key-fkey"], ["F10", "F10", "key-fkey"], ["F11", "F11", "key-fkey"], ["F12", "F12", "key-fkey"], "SPACER", ], ], main: [ [ ["~", "asciitilde"], ["1"], ["2"], ["3"], ["4"], ["5"], ["6"], ["7"], ["8"], ["9"], ["0"], ["-", "minus"], ["=", "equal"], ["BackSpace", "BackSpace", "key-backspace"], ], [ ["Tab", "Tab", "key-tab", "modifier"], ["q"], ["w"], ["e"], ["r"], ["t"], ["y"], ["u"], ["i"], ["o"], ["p"], ["[", "bracketleft"], ["]", "bracketright"], ["\\", "backslash"], ], [ ["Caps", "Caps_Lock", "key-caps", "modifier"], ["a"], ["s"], ["d"], ["f"], ["g"], ["h"], ["j"], ["k"], ["l"], [";", "semicolon"], ["'", "quote"], ["Enter", "Return", "key-return"], ], [ ["Shift", "shift", "key-shift-l", "modifier"], [",", "comma"], [".", "period"], ["/", "slash"], ["z"], ["x"], ["c"], ["v"], ["b"], ["n"], ["m"], ["Shift", "shift", "key-shift-r", "modifier"], ], [ ["Ctrl", "control", "key-ctrl", "modifier"], ["Win", "super", "", "modifier"], ["Alt", "alt", "", "modifier"], ["Space", "space", "key-space"], ["AltGr", "alt", "", "modifier"], ["Ctrl", "control", "key-ctrl", "modifier"], ], ], special: [ [ ["Print", "Print", "key-special"], ["Scroll", "Scroll", "key-special"], ["Pause", "Pause", "key-special"], ["None", "None", "key-special"], ], [ ["Insert", "Insert", "key-special"], ["Home", "Home", "key-special"], ["P_Up", "Page_Up", "key-special"], ], [ ["Del", "Delete", "key-special"], ["End", "End", "key-special"], ["P_Down", "Page_Down", "key-special"], ], ], arrows: [ [ ["Left", "Left", "key-special"], ["Up", "Up", "key-special"], ["Down", "Down", "key-special"], ["Right", "Right", "key-special"], ], ], }, azerty: { fkeys: [ [ ["Escape"], "SPACER", ["F1", "F1", "key-fkey"], ["F2", "F2", "key-fkey"], ["F3", "F3", "key-fkey"], ["F4", "F4", "key-fkey"], "SPACER", ["F5", "F5", "key-fkey"], ["F6", "F6", "key-fkey"], ["F7", "F7", "key-fkey"], ["F8", "F8", "key-fkey"], "SPACER", ["F9", "F9", "key-fkey"], ["F10", "F10", "key-fkey"], ["F11", "F11", "key-fkey"], ["F12", "F12", "key-fkey"], "SPACER", ], ], main: [ [ ["²", "asciicircum"], ["1"], ["2"], ["3"], ["4"], ["5"], ["6"], ["7"], ["8"], ["9"], ["0"], ["°", "degree"], ["+", "plus"], ["BackSpace", "BackSpace", "key-backspace"], ], [ ["Tab", "Tab", "key-tab", "modifier"], ["a"], ["z"], ["e"], ["r"], ["t"], ["y"], ["u"], ["i"], ["o"], ["p"], ["^", "asciicircum"], ["$", "dollar"], ["Return", "Return", "key-return"], ], [ ["Caps", "Caps_Lock", "key-caps", "modifier"], ["q"], ["s"], ["d"], ["f"], ["g"], ["h"], ["j"], ["k"], ["l"], ["m"], ["ù", "grave"], ["*", "asterisk"], ], [ ["Shift", "shift", "key-shift-l", "modifier"], [" { if (!str) return “”; return str .replace(/&/g, “&”) .replace(//g, “>”) .replace(/”/g, “"”) .replace(/’/g, “'”); }; const escapeAttr = (str) => { if (!str) return “”; return str.replace(/”/g, “"”); }; const normalizeKey = (key) => { if (!key) return “”; return key .trim() .replace(/^;+|;+$/g, “”) .replace(/;{2,}/g, “;”); }; const getContext = (value) => { if (!value || !value.includes(“/”)) { return “global”; } const [prefix, view] = value.split(“/”); if (prefix === “views”) { if (view && view.startsWith(“darkroom”)) return “darkroom”; if (view && view.startsWith(“lighttable”)) return “lighttable”; return “lighttable”; // Default for ‘views’ is lighttable } if ([“actions”, “iop”, “utility”].includes(prefix)) { return “darkroom”; } return “global”; }; const parseFileContent = (content) => { const lines = content.split(“\n”); const parsedShortcuts = []; nextId = 0; lines.forEach((line) => { line = line.trim(); if (line.startsWith(“#”) || !line) return; if (line.includes(“=”)) { const [key, value] = line.split(“=”, 2); if (key) { const trimmedValue = value.trim(); parsedShortcuts.push({ id: nextId++, key: key.trim(), value: trimmedValue, context: getContext(trimmedValue), }); } } }); return parsedShortcuts; }; const processAndRenderContent = (content, sourceName) => { try { shortcuts = parseFileContent(content); fileInfo.textContent = `Loaded from “${sourceName}”. Found ${shortcuts.length} shortcuts.`; mainContent.classList.remove(“d-none”); renderAll(); } catch (err) { console.error(“Error processing file content:”, err); fileInfo.textContent = `Error: Could not process content from “${sourceName}”. Check console for details.`; mainContent.classList.add(“d-none”); } }; const renderAll = () => { renderKeyboard(); renderTable(); renderFilterInfo(); }; const getKeyboardMap = () => { const keyMap = {}; let shortcutsToDisplay = shortcuts; if (currentKeyboardContext !== “all”) { shortcutsToDisplay = shortcuts.filter( (s) => s.context === currentKeyboardContext, ); } shortcutsToDisplay.forEach((entry) => { const parts = entry.key .toLowerCase() .split(“;”) .map((k) => k.trim()); parts.forEach((part) => { if (!part) return; if (!keyMap[part]) keyMap[part] = []; keyMap[part].push( `[${entry.context}] ${escapeHTML(entry.key)} = ${escapeHTML(entry.value)}`, ); }); }); return keyMap; }; // — RENDER FUNCTIONS — const renderKeyboard = () => { const keyMap = getKeyboardMap(); keyboardContainer.innerHTML = “”; const createKeyElement = (keyInfo) => { if (!keyInfo) return ‘
‘; if (keyInfo === “SPACER”) return ‘
‘; const [ displayText, dataKey = displayText.toLowerCase(), cssClass = “”, modifierClass = “”, ] = keyInfo; const keyId = dataKey.toLowerCase(); if (!keyId) return “”; const isAssigned = keyMap[keyId]; const isSelected = currentFilterKeys.includes(keyId); const tooltip = isAssigned ? `${keyMap[keyId].join(“\n”)}` : “”; return `
${displayText}${tooltip}
`; }; Object.entries(KEYBOARD_LAYOUTS[currentLayout]).forEach( ([blockName, layout]) => { const blockContainer = document.createElement(“div”); blockContainer.classList.add( “keyboard-block”, `keyboard-${blockName}`, ); layout.forEach((row) => { const rowContainer = document.createElement(“div”); rowContainer.classList.add(“key-row”); row.forEach((keyInfo) => { rowContainer.innerHTML += createKeyElement(keyInfo); }); blockContainer.appendChild(rowContainer); }); keyboardContainer.appendChild(blockContainer); }, ); }; const renderTable = () => { let displayData = […shortcuts]; if (currentSearchTerm) { const lowerCaseSearchTerm = currentSearchTerm.toLowerCase(); displayData = displayData.filter( (entry) => entry.key .toLowerCase() .includes(lowerCaseSearchTerm) || entry.value .toLowerCase() .includes(lowerCaseSearchTerm) || entry.context .toLowerCase() .includes(lowerCaseSearchTerm), ); } if (currentFilterKeys.length > 0) { displayData = displayData.filter((entry) => { const entryKeys = entry.key .toLowerCase() .split(“;”) .map((k) => k.trim()); return currentFilterKeys.every((filterKey) => entryKeys.includes(filterKey), ); }); } switch (currentSortBy) { case “key”: displayData.sort((a, b) => a.key.localeCompare(b.key)); break; case “value”: displayData.sort((a, b) => a.value.localeCompare(b.value), ); break; } tableBody.innerHTML = displayData.length === 0 && !document.querySelector(“.add-new-row”) ? ‘No shortcuts found for the current filter.‘ : displayData .map( (entry) => `${entry.context} `, ) .join(“”); }; const renderFilterInfo = () => { if (currentFilterKeys.length > 0) { filterInfo.innerHTML = `Filter active: ${currentFilterKeys.join(” + “)} `; } else { filterInfo.innerHTML = “”; } }; // — EVENT HANDLERS — fileInput.addEventListener(“change”, (event) => { const file = event.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = (e) => { processAndRenderContent(e.target.result, file.name); }; reader.readAsText(file); }); sortSelect.addEventListener(“change”, (e) => { currentSortBy = e.target.value; renderTable(); }); searchInput.addEventListener(“input”, (e) => { currentSearchTerm = e.target.value; renderTable(); }); downloadButton.addEventListener(“click”, () => { const fileContent = shortcuts .map((entry) => `${entry.key}=${entry.value}`) .join(“\n”); const blob = new Blob([fileContent], { type: “text/plain;charset=utf-8”, }); const a = document.createElement(“a”); a.href = URL.createObjectURL(blob); a.download = “shortcutsrc”; document.body.appendChild(a); a.click(); document.body.removeChild(a); }); addShortcutButton.addEventListener(“click”, () => { if (document.querySelector(“.add-new-row”)) return; const newRow = document.createElement(“tr”); newRow.classList.add(“add-new-row”); newRow.innerHTML = `– `; tableBody.prepend(newRow); }); keyboardContainer.addEventListener(“click”, (e) => { const keyElement = e.target.closest(“.filter-key”); if (!keyElement) return; const filterKey = keyElement.dataset.key; if (e.shiftKey) { const index = currentFilterKeys.indexOf(filterKey); if (index > -1) { currentFilterKeys.splice(index, 1); } else { currentFilterKeys.push(filterKey); } } else { currentFilterKeys = currentFilterKeys.length === 1 && currentFilterKeys[0] === filterKey ? [] : [filterKey]; } renderAll(); }); contextFilterButtons.addEventListener(“click”, (e) => { const button = e.target.closest(“button”); if (!button) return; currentKeyboardContext = button.dataset.context; contextFilterButtons .querySelectorAll(“button”) .forEach((btn) => { btn.classList.remove( “btn-primary”, “btn-outline-secondary”, ); if (btn === button) { btn.classList.add(“btn-primary”); } else { btn.classList.add(“btn-outline-secondary”); } }); renderKeyboard(); }); filterInfo.addEventListener(“click”, (e) => { if (e.target.id === “clear-filter-btn”) { currentFilterKeys = []; renderAll(); } }); tableBody.addEventListener(“click”, (e) => { const row = e.target.closest(“tr”); if (!row) return; const handleUpdate = (isNew) => { const keyInput = row.querySelector(“td:nth-child(1) input”); const valueInput = row.querySelector( “td:nth-child(2) input”, ); const newKey = normalizeKey(keyInput.value); const newValue = valueInput.value.trim(); if (!newKey || !newValue) { alert(“Key and Value cannot be empty.”); return; } const newContext = getContext(newValue); const entryId = isNew ? -1 : parseInt(row.dataset.id, 10); const conflict = shortcuts.find( (s) => s.id !== entryId && s.key === newKey && (s.context === newContext || s.context === “global” || newContext === “global”), ); if (conflict) { alert( `Conflict found! The key ‘${newKey}’ is already assigned for the context ‘${newContext}’ (Action: ${conflict.value}). Global shortcuts cannot be overwritten in a specific context and vice versa with the same key.`, ); return; } if (isNew) { shortcuts.push({ id: nextId++, key: newKey, value: newValue, context: newContext, }); } else { const entry = shortcuts.find((s) => s.id === entryId); if (entry) { entry.key = newKey; entry.value = newValue; entry.context = newContext; } } renderAll(); }; if (e.target.classList.contains(“save-new-btn”)) handleUpdate(true); if (e.target.classList.contains(“update-btn”)) handleUpdate(false); if (e.target.classList.contains(“cancel-new-btn”)) row.remove(); if (e.target.classList.contains(“delete-btn”)) { const entryId = parseInt(row.dataset.id, 10); const entryIndex = shortcuts.findIndex( (s) => s.id === entryId, ); if ( entryIndex > -1 && confirm( `Really delete shortcut “${shortcuts[entryIndex].key}”?`, ) ) { shortcuts.splice(entryIndex, 1); renderAll(); } } }); const loadFromUrl = async () => { const urlParams = new URLSearchParams(window.location.search); const srcUrl = urlParams.get(“src”); if (srcUrl) { const fileInputCard = fileInput.closest(“.card”); if (fileInputCard) { fileInputCard.classList.add(“d-none”); } try { fileInfo.textContent = `Loading from URL: ${srcUrl}`; const response = await fetch(srcUrl); if (!response.ok) { throw new Error( `HTTP error! status: ${response.status}`, ); } const content = await response.text(); processAndRenderContent(content, srcUrl); } catch (err) { console.error( “Error fetching or processing file from URL:”, err, ); fileInfo.textContent = `Error: Could not load file from URL. ${err.message}`; mainContent.classList.add(“d-none”); if (fileInputCard) { fileInputCard.classList.remove(“d-none”); } } } }; document.body.addEventListener(“dragover”, (event) => { event.preventDefault(); document.body.classList.add(“drag-over”); }); document.body.addEventListener(“dragleave”, () => { document.body.classList.remove(“drag-over”); }); document.body.addEventListener(“drop”, (event) => { event.preventDefault(); document.body.classList.remove(“drag-over”); const file = event.dataTransfer.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = (e) => { processAndRenderContent(e.target.result, file.name); }; reader.readAsText(file); }); // — INITIALIZATION — document.addEventListener(“DOMContentLoaded”, () => { if ( preloadedShortcutsrcContent && preloadedShortcutsrcContent.trim() !== “” ) { const fileInputCard = fileInput.closest(“.card”); if (fileInputCard) { fileInputCard.classList.add(“d-none”); } processAndRenderContent( preloadedShortcutsrcContent, “pre-loaded variable”, ); } else { loadFromUrl(); } // Standard-Theme auf “dark” setzen document.body.classList.add(“dark-mode”); localStorage.setItem(“theme”, “dark”); // QWERTZ als Standard-Tastaturbelegung keyboardLayoutSelect.value = “qwertz”; currentLayout = “qwertz”; renderAll(); }); // — THEME — document .getElementById(“theme-toggle”) .addEventListener(“click”, () => { document.body.classList.toggle(“dark-mode”); localStorage.setItem( “theme”, document.body.classList.contains(“dark-mode”) ? “dark” : “light”, ); }); if (localStorage.getItem(“theme”) === “dark”) { document.body.classList.add(“dark-mode”); } // — KEYBOARD LAYOUT — keyboardLayoutSelect.addEventListener(“change”, (e) => { currentLayout = e.target.value; renderAll(); });

Geef een reactie