diff --git a/tests/test_keybinding_utils.mjs b/tests/test_keybinding_utils.mjs index e991fd8..260741e 100644 --- a/tests/test_keybinding_utils.mjs +++ b/tests/test_keybinding_utils.mjs @@ -1,44 +1,10 @@ -import fs from 'node:fs'; -import path from 'node:path'; import test from 'node:test'; import assert from 'node:assert/strict'; - -const projectRoot = path.resolve(import.meta.dirname, '..'); -const modelResolverSource = fs.readFileSync( - path.join(projectRoot, 'web/resolver/model_resolver.js'), - 'utf8' -); - -function extractFunction(source, functionName) { - const signature = new RegExp(`\\nfunction ${functionName}\\s*\\(`); - const match = signature.exec(source); - assert.ok(match, `Could not find ${functionName}`); - const parenStart = source.indexOf('(', match.index); - let parenDepth = 0; - let parenEnd = -1; - for (let i = parenStart; i < source.length; i += 1) { - if (source[i] === '(') parenDepth += 1; - if (source[i] === ')') parenDepth -= 1; - if (parenDepth === 0) { - parenEnd = i; - break; - } - } - const braceStart = source.indexOf('{', parenEnd); - let braceDepth = 0; - for (let i = braceStart; i < source.length; i += 1) { - if (source[i] === '{') braceDepth += 1; - if (source[i] === '}') braceDepth -= 1; - if (braceDepth === 0) { - return `function ${functionName}${source.slice(parenStart, parenEnd + 1)} ${source.slice(braceStart, i + 1)}`; - } - } - throw new Error(`Could not parse ${functionName}`); -} - -const serializeKeybindingCombo = eval(`(${extractFunction(modelResolverSource, 'serializeKeybindingCombo')})`); -const keybindingsEqual = eval(`(${extractFunction(modelResolverSource, 'keybindingsEqual')})`); -const getComboLabel = eval(`(${extractFunction(modelResolverSource, 'getComboLabel')})`); +import { + serializeKeybindingCombo, + keybindingsEqual, + getComboLabel, +} from '../web/resolver/utils/keybinding_utils.js'; test('keybinding serialization is stable for equivalent combos', () => { assert.equal(serializeKeybindingCombo({ key: 'k', ctrl: true, shift: false }), 'K:true:false:false'); diff --git a/web/resolver/model_resolver.js b/web/resolver/model_resolver.js index c3fd978..3cd80a4 100644 --- a/web/resolver/model_resolver.js +++ b/web/resolver/model_resolver.js @@ -6,6 +6,11 @@ import { logger as frontendLogger } from "../log_system/logger.js"; import { loadStylesWhenNeeded } from "../utils/css_loader.js"; import { ResolverManagerDialog } from "./resolver_dialog.js"; import { showNotification } from "../utils/notification_utils.js"; +import { + serializeKeybindingCombo, + keybindingsEqual, + getComboLabel, +} from "./utils/keybinding_utils.js"; import { buildModelResolverNodeMenu, getImmediateModelsForNode, @@ -52,51 +57,6 @@ function getKeybindingSetting(id) { } } -function serializeKeybindingCombo(combo = {}) { - return [ - String(combo.key || "").toUpperCase(), - String(Boolean(combo.ctrl)), - String(Boolean(combo.alt)), - String(Boolean(combo.shift)), - ].join(":"); -} - -function keybindingsEqual(left, right) { - return Boolean( - left - && right - && left.commandId === right.commandId - && (left.targetElementId || "") === (right.targetElementId || "") - && serializeKeybindingCombo(left.combo) === serializeKeybindingCombo(right.combo) - ); -} - -function getComboLabel(combo = {}) { - const parts = []; - if (combo.ctrl) parts.push("Ctrl"); - if (combo.alt) parts.push("Alt"); - if (combo.shift) parts.push("Shift"); - - const keyLabels = { - " ": "Space", - ArrowUp: "Up", - ArrowDown: "Down", - ArrowLeft: "Left", - ArrowRight: "Right", - Backspace: "Backspace", - Delete: "Delete", - Enter: "Enter", - Escape: "Esc", - Tab: "Tab", - }; - const key = String(combo.key || "").trim(); - if (key) { - parts.push(keyLabels[key] || (key.length === 1 ? key.toUpperCase() : key)); - } - - return parts.join("+"); -} - function applyStoredFrontendLoggingPreference() { const stored = localStorage.getItem('ModelResolver.frontendLogsEnabled'); if (stored !== null) { diff --git a/web/resolver/utils/keybinding_utils.js b/web/resolver/utils/keybinding_utils.js new file mode 100644 index 0000000..7b718bb --- /dev/null +++ b/web/resolver/utils/keybinding_utils.js @@ -0,0 +1,44 @@ +export function serializeKeybindingCombo(combo = {}) { + return [ + String(combo.key || "").toUpperCase(), + String(Boolean(combo.ctrl)), + String(Boolean(combo.alt)), + String(Boolean(combo.shift)), + ].join(":"); +} + +export function keybindingsEqual(left, right) { + return Boolean( + left + && right + && left.commandId === right.commandId + && (left.targetElementId || "") === (right.targetElementId || "") + && serializeKeybindingCombo(left.combo) === serializeKeybindingCombo(right.combo) + ); +} + +export function getComboLabel(combo = {}) { + const parts = []; + if (combo.ctrl) parts.push("Ctrl"); + if (combo.alt) parts.push("Alt"); + if (combo.shift) parts.push("Shift"); + + const keyLabels = { + " ": "Space", + ArrowUp: "Up", + ArrowDown: "Down", + ArrowLeft: "Left", + ArrowRight: "Right", + Backspace: "Backspace", + Delete: "Delete", + Enter: "Enter", + Escape: "Esc", + Tab: "Tab", + }; + const key = String(combo.key || "").trim(); + if (key) { + parts.push(keyLabels[key] || (key.length === 1 ? key.toUpperCase() : key)); + } + + return parts.join("+"); +}