Add find and replace shortcut definitions to the shortcut registry with Mod+F and Mod+R defaults. Route Mod-R through App → ContentArea to dispatch to either the query editor replace panel or data grid refresh based on focus context. Add isModRShortcut helper and tests.
178 lines
6.3 KiB
TypeScript
178 lines
6.3 KiB
TypeScript
import { strict as assert } from "node:assert";
|
|
import test from "node:test";
|
|
import {
|
|
eventToShortcut,
|
|
isBrowserReloadShortcut,
|
|
isCancelSearchShortcut,
|
|
isCloseTabShortcut,
|
|
isExecuteSqlShortcut,
|
|
isFocusSearchShortcut,
|
|
isModRShortcut,
|
|
isNewQueryShortcut,
|
|
isObjectSourceSaveShortcutTarget,
|
|
isRefreshDataShortcut,
|
|
isSaveShortcut,
|
|
isCopyCurrentRowShortcut,
|
|
isDeleteCurrentRowShortcut,
|
|
isToggleTransposeShortcut,
|
|
} from "../../apps/desktop/src/lib/keyboardShortcuts.ts";
|
|
import { shortcutToCodeMirrorKey } from "../../apps/desktop/src/lib/shortcutRegistry.ts";
|
|
|
|
test("matches Cmd+Enter for SQL execution", () => {
|
|
assert.equal(isExecuteSqlShortcut({ key: "Enter", metaKey: true }), true);
|
|
});
|
|
|
|
test("matches custom shortcut settings for SQL execution", () => {
|
|
assert.equal(isExecuteSqlShortcut({ key: "Enter", metaKey: true }, { executeSql: "Shift+Mod+Enter" } as any), false);
|
|
assert.equal(
|
|
isExecuteSqlShortcut(
|
|
{ key: "Enter", metaKey: true, shiftKey: true } as any,
|
|
{
|
|
executeSql: "Shift+Mod+Enter",
|
|
} as any,
|
|
),
|
|
true,
|
|
);
|
|
});
|
|
|
|
test("records custom shortcuts from keydown events", () => {
|
|
assert.equal(eventToShortcut({ key: "r", metaKey: true, shiftKey: true } as any), "Shift+Mod+R");
|
|
assert.equal(eventToShortcut({ key: "F2" } as any), "F2");
|
|
assert.equal(eventToShortcut({ key: "Control", ctrlKey: true } as any), null);
|
|
});
|
|
|
|
test("converts custom shortcuts to CodeMirror key names", () => {
|
|
assert.equal(shortcutToCodeMirrorKey("Shift+Mod+R"), "Shift-Mod-r");
|
|
assert.equal(shortcutToCodeMirrorKey("Mod+/"), "Mod-/");
|
|
});
|
|
|
|
test("matches Ctrl+Enter for SQL execution", () => {
|
|
assert.equal(isExecuteSqlShortcut({ key: "Enter", ctrlKey: true }), true);
|
|
});
|
|
|
|
test("matches Cmd+T for opening a new query", () => {
|
|
assert.equal(isNewQueryShortcut({ key: "t", metaKey: true }), true);
|
|
});
|
|
|
|
test("matches custom shortcut settings for opening a new query", () => {
|
|
assert.equal(isNewQueryShortcut({ key: "t", metaKey: true }, { newQuery: "Shift+Mod+N" } as any), false);
|
|
assert.equal(
|
|
isNewQueryShortcut({ key: "n", ctrlKey: true, shiftKey: true } as any, { newQuery: "Shift+Mod+N" } as any),
|
|
true,
|
|
);
|
|
});
|
|
|
|
test("ignores Enter without modifier", () => {
|
|
assert.equal(isExecuteSqlShortcut({ key: "Enter" }), false);
|
|
});
|
|
|
|
test("ignores composing input events", () => {
|
|
assert.equal(isExecuteSqlShortcut({ key: "Enter", metaKey: true, isComposing: true }), false);
|
|
});
|
|
|
|
test("matches Cmd+W for closing query tabs", () => {
|
|
assert.equal(isCloseTabShortcut({ key: "w", metaKey: true }), true);
|
|
});
|
|
|
|
test("ignores Ctrl+W for closing query tabs", () => {
|
|
assert.equal(isCloseTabShortcut({ key: "w", ctrlKey: true }), false);
|
|
});
|
|
|
|
test("matches Ctrl+F for focusing search", () => {
|
|
assert.equal(isFocusSearchShortcut({ key: "f", ctrlKey: true }), true);
|
|
});
|
|
|
|
test("matches Cmd+F for focusing search", () => {
|
|
assert.equal(isFocusSearchShortcut({ key: "F", metaKey: true }), true);
|
|
});
|
|
|
|
test("matches F5 for refreshing data", () => {
|
|
assert.equal(isRefreshDataShortcut({ key: "F5" }), true);
|
|
});
|
|
|
|
test("matches configurable shortcut for toggling transpose view", () => {
|
|
assert.equal(isToggleTransposeShortcut({ key: "Tab" }), true);
|
|
assert.equal(isToggleTransposeShortcut({ key: "Tab" }, { toggleTranspose: "Alt+T" } as any), false);
|
|
assert.equal(isToggleTransposeShortcut({ key: "t", altKey: true }, { toggleTranspose: "Alt+T" } as any), true);
|
|
});
|
|
|
|
test("matches custom shortcut settings for refreshing data", () => {
|
|
assert.equal(isRefreshDataShortcut({ key: "F5" }, { refreshData: "Shift+Mod+R" } as any), false);
|
|
assert.equal(
|
|
isRefreshDataShortcut({ key: "r", metaKey: true, shiftKey: true } as any, { refreshData: "Shift+Mod+R" } as any),
|
|
true,
|
|
);
|
|
});
|
|
|
|
test("detects browser reload shortcuts for desktop suppression", () => {
|
|
assert.equal(isBrowserReloadShortcut({ key: "r", ctrlKey: true }), true);
|
|
assert.equal(isBrowserReloadShortcut({ key: "R", metaKey: true, shiftKey: true }), true);
|
|
assert.equal(isBrowserReloadShortcut({ key: "F5" }), true);
|
|
assert.equal(isBrowserReloadShortcut({ key: "r", altKey: true, ctrlKey: true }), false);
|
|
assert.equal(isBrowserReloadShortcut({ key: "r", ctrlKey: true, isComposing: true }), false);
|
|
});
|
|
|
|
test("matches Mod-R without shift or alt for scoped refresh and replace", () => {
|
|
assert.equal(isModRShortcut({ key: "r", ctrlKey: true }), true);
|
|
assert.equal(isModRShortcut({ key: "R", metaKey: true }), true);
|
|
assert.equal(isModRShortcut({ key: "R", metaKey: true, shiftKey: true }), false);
|
|
assert.equal(isModRShortcut({ key: "r", ctrlKey: true, altKey: true }), false);
|
|
});
|
|
|
|
test("ignores focus search shortcut while composing", () => {
|
|
assert.equal(isFocusSearchShortcut({ key: "f", ctrlKey: true, isComposing: true }), false);
|
|
});
|
|
|
|
test("ignores Alt+F for focusing search", () => {
|
|
assert.equal(isFocusSearchShortcut({ key: "f", altKey: true }), false);
|
|
});
|
|
|
|
test("matches Cmd+S for saving", () => {
|
|
assert.equal(isSaveShortcut({ key: "s", metaKey: true }), true);
|
|
});
|
|
|
|
test("matches Mod+D for copying current row", () => {
|
|
assert.equal(isCopyCurrentRowShortcut({ key: "d", metaKey: true }), true);
|
|
});
|
|
|
|
test("matches Delete for deleting current row", () => {
|
|
assert.equal(isDeleteCurrentRowShortcut({ key: "Delete" }), true);
|
|
});
|
|
|
|
test("matches Ctrl+S for saving", () => {
|
|
assert.equal(isSaveShortcut({ key: "S", ctrlKey: true }), true);
|
|
});
|
|
|
|
test("ignores save shortcut while composing", () => {
|
|
assert.equal(isSaveShortcut({ key: "s", metaKey: true, isComposing: true }), false);
|
|
});
|
|
|
|
test("ignores Alt+S for saving", () => {
|
|
assert.equal(isSaveShortcut({ key: "s", altKey: true }), false);
|
|
});
|
|
|
|
test("detects object source editor targets for contextual save", () => {
|
|
const target = {
|
|
closest: (selector: string) =>
|
|
selector === "[data-object-source-editor], [data-object-source-preview]" ? {} : null,
|
|
};
|
|
|
|
assert.equal(isObjectSourceSaveShortcutTarget(target), true);
|
|
});
|
|
|
|
test("ignores regular editor targets for contextual object source save", () => {
|
|
const target = {
|
|
closest: () => null,
|
|
};
|
|
|
|
assert.equal(isObjectSourceSaveShortcutTarget(target), false);
|
|
});
|
|
|
|
test("matches Escape for cancelling search", () => {
|
|
assert.equal(isCancelSearchShortcut({ key: "Escape" }), true);
|
|
});
|
|
|
|
test("ignores cancelling search while composing", () => {
|
|
assert.equal(isCancelSearchShortcut({ key: "Escape", isComposing: true }), false);
|
|
});
|