142 Zeilen
3.2 KiB
JavaScript
142 Zeilen
3.2 KiB
JavaScript
/**
|
|
* TASKMATE - Keyboard Shortcuts Module
|
|
* =====================================
|
|
* Global keyboard shortcuts (only non-browser-conflicting)
|
|
*/
|
|
|
|
import store from './store.js';
|
|
import { $ } from './utils.js';
|
|
|
|
class ShortcutsManager {
|
|
constructor() {
|
|
this.shortcuts = new Map();
|
|
this.isEnabled = true;
|
|
|
|
this.registerDefaultShortcuts();
|
|
this.bindEvents();
|
|
}
|
|
|
|
bindEvents() {
|
|
document.addEventListener('keydown', (e) => this.handleKeydown(e));
|
|
}
|
|
|
|
handleKeydown(e) {
|
|
// Don't handle shortcuts when typing in inputs
|
|
if (this.isInputFocused()) return;
|
|
|
|
// Don't handle when modals are open (except escape)
|
|
if (store.get('openModals').length > 0 && e.key !== 'Escape') return;
|
|
|
|
// Don't handle when disabled
|
|
if (!this.isEnabled) return;
|
|
|
|
const combo = this.getKeyCombo(e);
|
|
const handler = this.shortcuts.get(combo);
|
|
|
|
if (handler) {
|
|
e.preventDefault();
|
|
handler(e);
|
|
}
|
|
}
|
|
|
|
getKeyCombo(e) {
|
|
const parts = [];
|
|
|
|
if (e.ctrlKey || e.metaKey) parts.push('Ctrl');
|
|
if (e.altKey) parts.push('Alt');
|
|
if (e.shiftKey) parts.push('Shift');
|
|
|
|
// Get the key
|
|
let key = e.key;
|
|
if (key === ' ') key = 'Space';
|
|
if (key.length === 1) key = key.toUpperCase();
|
|
|
|
parts.push(key);
|
|
|
|
return parts.join('+');
|
|
}
|
|
|
|
isInputFocused() {
|
|
const activeElement = document.activeElement;
|
|
const tagName = activeElement?.tagName.toLowerCase();
|
|
const isContentEditable = activeElement?.contentEditable === 'true';
|
|
|
|
return ['input', 'textarea', 'select'].includes(tagName) || isContentEditable;
|
|
}
|
|
|
|
// =====================
|
|
// SHORTCUT REGISTRATION
|
|
// =====================
|
|
|
|
register(combo, handler, description = '') {
|
|
this.shortcuts.set(combo, handler);
|
|
// Store description for help display
|
|
handler.description = description;
|
|
}
|
|
|
|
unregister(combo) {
|
|
this.shortcuts.delete(combo);
|
|
}
|
|
|
|
enable() {
|
|
this.isEnabled = true;
|
|
}
|
|
|
|
disable() {
|
|
this.isEnabled = false;
|
|
}
|
|
|
|
// =====================
|
|
// DEFAULT SHORTCUTS
|
|
// =====================
|
|
|
|
registerDefaultShortcuts() {
|
|
// Only Escape - close modals (doesn't conflict with browser)
|
|
this.register('Escape', () => this.handleEscape(), 'Schließen / Abbrechen');
|
|
}
|
|
|
|
// =====================
|
|
// SHORTCUT HANDLERS
|
|
// =====================
|
|
|
|
handleEscape() {
|
|
const openModals = store.get('openModals');
|
|
|
|
if (openModals.length > 0) {
|
|
// Close the topmost modal
|
|
const topModal = openModals[openModals.length - 1];
|
|
window.dispatchEvent(new CustomEvent('modal:close', {
|
|
detail: { modalId: topModal }
|
|
}));
|
|
} else {
|
|
// Clear selection
|
|
store.clearSelection();
|
|
}
|
|
}
|
|
|
|
showHelp() {
|
|
// No longer needed - shortcuts removed
|
|
}
|
|
|
|
// =====================
|
|
// HELP DISPLAY
|
|
// =====================
|
|
|
|
getShortcutsList() {
|
|
// Minimal shortcuts that don't conflict with browser
|
|
return {
|
|
actions: {
|
|
title: 'Aktionen',
|
|
shortcuts: [
|
|
{ combo: 'Escape', description: 'Dialog schließen / Auswahl aufheben' }
|
|
]
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
// Create and export singleton
|
|
const shortcutsManager = new ShortcutsManager();
|
|
|
|
export default shortcutsManager;
|