UNPKG

paella-core

Version:
238 lines (213 loc) 8.42 kB
import Plugin from 'paella-core/js/core/Plugin'; import { loadPluginsOfType } from 'paella-core/js/core/plugin_tools'; import PopUp from './PopUp'; const getModifierStatus = sc => { return `alt:${sc.keyModifiers?.altKey || false}, ctrl:${sc.keyModifiers?.ctrlKey || false}, shift:${sc.keyModifiers?.shiftKey || false}` } const getShortcutHash = (sc) => { const hash = `${sc.keyCode}_${getModifierStatus(sc)}`; return hash; } const addKeyModifiersObject = sc => { sc.keyModifiers = sc.keyModifiers || {}; sc.keyModifiers.altKey = sc.keyModifiers.altKey || false; sc.keyModifiers.shiftKey = sc.keyModifiers.shiftKey || false; sc.keyModifiers.ctrlKey = sc.keyModifiers.ctrlKey || false; } export const getShortcuts = (player) => { const enabledShortcuts = []; for (const keyCode in player.__shortcuts__) { const shortcut = player.__shortcuts__[keyCode]; shortcut.forEach(sc => { if (!sc.disabled) { enabledShortcuts.push(sc); } }); } return enabledShortcuts; } export const pauseCaptureShortcuts = (player) => { player.__pauseCaptureShortcuts__ = true; } export const resumeCaptureShortcuts = (player) => { player.__pauseCaptureShortcuts__ = false; } export async function loadKeyShortcutPlugins(player) { player.__shortcuts__ = player.__shortcuts__ || {}; // If the page contains more than one paella player, the first one to register will be the one that will handle the keyboard shortcuts if (!window.__paella_shortcuts_player__) { window.__paella_shortcuts_player__ = player; } else { player.log.warn("Warning: more than one paella player instance with enabled shortcut plugins."); player.log.warn("Check your code to ensure that only one instance of paella player registers keyboard shortcut plugins."); return; } await loadPluginsOfType(player, "keyshortcut", async (plugin) => { const shortcuts = await plugin.getKeys(); shortcuts.forEach(shortcut => { player.__shortcuts__[shortcut.keyCode] = player.__shortcuts__[shortcut.keyCode] || []; shortcut.plugin = plugin; player.__shortcuts__[shortcut.keyCode].push(shortcut); }); const dicts = await plugin.getDictionaries(); for (const key in dicts) { const dict = dicts[key]; player.addDictionary(key, dict); } for (const keyCode in player.__shortcuts__) { const shortcuts = player.__shortcuts__[keyCode]; const hashes = {}; if (shortcuts.length > 0) { shortcuts.forEach(shortcut => { const hash = getShortcutHash(shortcut); addKeyModifiersObject(shortcut); if (!hashes[hash]) { hashes[hash] = shortcut; } else { player.log.warn(`Collision detected in shortcut for key code ${ keyCode }`); const enabledShortcut = hashes[hash]; player.log.warn('Enabled shortcut:'); player.log.warn(`plugin: ${enabledShortcut.plugin.name}, keyCode: ${enabledShortcut.keyCode}, modifiers: ${getModifierStatus(enabledShortcut)}, description: ${enabledShortcut.description}`); player.log.warn('Collision shortcut (disabled):'); player.log.warn(`plugin: ${shortcut.plugin.name}, keyCode: ${shortcut.keyCode}, modifiers: ${getModifierStatus(shortcut)}, description: ${shortcut.description}`); shortcut.disabled = true; } }) } } }); player.__paella_key_event_listener__ = async (event) => { if (player.__pauseCaptureShortcuts__) { player.log.info("Capture shortcuts paused. Ignoring loadKeyShortcutPlugins call."); return; } const validFocus = () => document.activeElement && document.activeElement !== document.body && !/video/i.test(document.activeElement.tagName); // Do not process the key if focus is outside paella-core container, but // catch key events if the focus is on body if (!player.containerElement.contains(document.activeElement) && !PopUp.Contains(document.activeElement) && document.activeElement !== document.body) { return; } // Exclude the action key when there are something focused, if the space bar is // being used as click action const clickWithSpacebar = player.config.accessibility?.clickWithSpacebar !== undefined ? player.config.accessibility?.clickWithSpacebar : true; if (clickWithSpacebar && event.code === "Space" && validFocus()) { return; } const shortcut = player.__shortcuts__[event.code]; if (shortcut) { await shortcut.forEach(async s => { const altStatus = !s.keyModifiers?.altKey || (s.keyModifiers?.altKey && event.altKey); const ctrlStatus = !s.keyModifiers?.ctrlKey || (s.keyModifiers?.ctrlKey && event.ctrlKey); const shiftStatus = !s.keyModifiers?.shiftKey || (s.keyModifiers?.shiftKey && event.shiftKey); if (altStatus && ctrlStatus && shiftStatus && !s.disabled) { await s.action(event); } else if (altStatus && ctrlStatus && shiftStatus && s.disabled) { player.log.warn("Shortcut not triggered due to collision:"); player.log.warn(`plugin: ${s.plugin.name}, keyCode: ${s.keyCode}, modifiers: ${getModifierStatus(s)}, description: ${s.description}`); } }); } } window.addEventListener("keyup", player.__paella_key_event_listener__); } export async function unloadKeyShortcutPlugins(player) { delete player.__shortcuts__; if (player == window.__paella_shortcuts_player__) { window.removeEventListener("keyup",player.__paella_key_event_listener__); delete window.__paella_key_event_listener__; delete window.__paella_shortcuts_player__; } } export const KeyCodes = { "Digit1": "Digit1", "Digit2": "Digit2", "Digit3": "Digit3", "Digit4": "Digit4", "Digit5": "Digit5", "Digit6": "Digit6", "Digit7": "Digit7", "Digit8": "Digit8", "Digit9": "Digit9", "Digit0": "Digit0", "KeyA": "KeyA", "KeyB": "KeyB", "KeyC": "KeyC", "KeyD": "KeyD", "KeyE": "KeyE", "KeyF": "KeyF", "KeyG": "KeyG", "KeyH": "KeyH", "KeyI": "KeyI", "KeyJ": "KeyJ", "KeyK": "KeyK", "KeyL": "KeyL", "KeyM": "KeyM", "KeyN": "KeyN", "KeyO": "KeyO", "KeyP": "KeyP", "KeyQ": "KeyQ", "KeyR": "KeyR", "KeyS": "KeyS", "KeyT": "KeyT", "KeyU": "KeyU", "KeyV": "KeyV", "KeyW": "KeyW", "KeyX": "KeyX", "KeyY": "KeyY", "KeyZ": "KeyZ", "Comma": "Comma", "Period": "Period", "Semicolon": "Semicolon", "Quote": "Quote", "BracketLeft": "BracketLeft", "BracketRight": "BracketRight", "Backquote": "Backquote", "Backslash": "Backslash", "Minus": "Minus", "Equal": "Equal", "AltLeft": "AltLeft", "AltRight": "AltRight", "CapsLock": "CapsLock", "ControlLeft": "ControlLeft", "ControlRight": "ControlRight", "OSLeft": "OSLeft", "OSRight": "OSRight", "ShiftLeft": "ShiftLeft", "ShiftRight": "ShiftRight", "ContextMenu": "ContextMenu", "Enter": "Enter", "Space": "Space", "Tab": "Tab", "Delete": "Delete", "End": "End", "Help": "Help", "Home": "Home", "Insert": "Insert", "PageDown": "PageDown", "PageUp": "PageUp", "ArrowDown": "ArrowDown", "ArrowLeft": "ArrowLeft", "ArrowRight": "ArrowRight", "ArrowUp": "ArrowUp", "Escape": "Escape", "PrintScreen": "PrintScreen", "ScrollLock": "ScrollLock", "Pause": "Pause" }; export default class KeyShortcutPlugin extends Plugin { get type() { return "keyshortcut"; } /** * * @returns [{ keyCode: KeyCode, keyModifiers: [KeyModifiers], description: string, action: async function }] */ async getKeys() { return []; } async getDictionaries() { return {} } }