fix(ai): liens sans vault, navigation clavier des menus et purge caches (BUG-013, BUG-014)
BUG-013: _openFileLink/_revealPath utilisent _activeVault() (contexte -> selection -> premier vault). BUG-014: navigation up/down geree au niveau du panneau en phase de capture, independante du focus. Caches: SW_VERSION v6 + migration qui purge tous les caches obsigate-*.
This commit is contained in:
@@ -1070,6 +1070,57 @@ async function main() {
|
||||
localStorage.clear();
|
||||
});
|
||||
|
||||
await test("active vault falls back to the first available vault", async () => {
|
||||
const stateMod = await import(pathToFileURL(path.join(JS_DIR, "state.js")).href);
|
||||
const prevVaults = stateMod.state.allVaults;
|
||||
const prevSelected = stateMod.state.selectedContextVault;
|
||||
stateMod.state.allVaults = [{ name: "V1" }, { name: "V2" }];
|
||||
stateMod.state.selectedContextVault = "all";
|
||||
const b = new BooksLM();
|
||||
b._vault = null;
|
||||
assert.equal(b._activeVault(), "V1", "first vault used for links/@ browsing");
|
||||
stateMod.state.selectedContextVault = "V2";
|
||||
assert.equal(b._activeVault(), "V2", "selected context vault takes precedence");
|
||||
stateMod.state.allVaults = prevVaults;
|
||||
stateMod.state.selectedContextVault = prevSelected;
|
||||
});
|
||||
|
||||
await test("menu navigation works from the panel, not only the textarea", async () => {
|
||||
localStorage.clear();
|
||||
globalThis.fetch = async (url) => {
|
||||
if (String(url).includes("/api/ai/skills")) {
|
||||
return {
|
||||
ok: true, status: 200,
|
||||
json: async () => ({
|
||||
skills: [
|
||||
{ id: "a", label: "Alpha", type: "skill", description: "d" },
|
||||
{ id: "b", label: "Beta", type: "skill", description: "d" },
|
||||
],
|
||||
commands: [],
|
||||
}),
|
||||
};
|
||||
}
|
||||
return { ok: true, status: 200, json: async () => ({}) };
|
||||
};
|
||||
const b = new BooksLM();
|
||||
b._panel = b._render();
|
||||
document.body.appendChild(b._panel);
|
||||
const ta = b._panel.querySelector("textarea");
|
||||
ta.value = "/";
|
||||
ta.selectionStart = ta.selectionEnd = 1;
|
||||
b._onComposerInput();
|
||||
await sleep(20);
|
||||
const items = () => Array.from(b._panel.querySelectorAll(".bookslm-command-menu .bookslm-menu-item"));
|
||||
assert.equal(items().length, 2);
|
||||
|
||||
// Dispatch on the panel itself (focus elsewhere) — the capture handler must
|
||||
// still navigate the menu.
|
||||
b._panel.dispatchEvent(new w.KeyboardEvent("keydown", { key: "ArrowDown", bubbles: true, cancelable: true }));
|
||||
assert.ok(items()[1].classList.contains("active"), "ArrowDown from the panel moves the highlight");
|
||||
b._panel.remove();
|
||||
localStorage.clear();
|
||||
});
|
||||
|
||||
// ── Summary ──
|
||||
console.log(`\n${passCount}/${testCount} tests passed`);
|
||||
if (passCount !== testCount) {
|
||||
|
||||
Reference in New Issue
Block a user