fix(hachidori): close an open pane after its attention is released

This commit is contained in:
sudacode committed 2026-10-11 00:54:01 -07:00
1 parent 0523beef2b
commit 6c295586cb
2 files changed
+46 -4

No files matched your search

+37 -1
View File
@@ -153,6 +153,10 @@ function installKeyboardTestGlobals() {
let selectionAddCount = 0;
let popupVisible = false;
let hachidoriPaneOpen = false;
const hachidoriHost = {
shadowRoot: { querySelectorAll: () => [{ hidden: false }] },
};
const popupIframe = {
tagName: 'IFRAME',
@@ -287,7 +291,10 @@ function installKeyboardTestGlobals() {
listeners.push(listener);
documentListeners.set(type, listeners);
},
querySelectorAll: () => {
querySelectorAll: (selector: string) => {
if (selector === HACHIDORI_HOST_SELECTOR) {
return hachidoriPaneOpen ? [hachidoriHost] : [];
}
if (popupVisible) {
return [popupIframe];
}
@@ -457,6 +464,9 @@ function installKeyboardTestGlobals() {
setPopupVisible: (value: boolean) => {
popupVisible = value;
},
setHachidoriPaneOpen: (value: boolean) => {
hachidoriPaneOpen = value;
},
setStatsToggleKey: (value: string) => {
statsToggleKey = value;
},
@@ -1313,6 +1323,32 @@ test('keyboard mode: lookup toggle opens a lookup during Hachidori attention wit
}
});
test('keyboard mode: lookup toggle closes an open Hachidori pane after attention is released', async () => {
const { ctx, handlers, testGlobals } = createKeyboardHandlerHarness();
try {
await handlers.setupMpvInputForwarding();
handlers.handleKeyboardModeToggleRequested();
// A selection drag leaves the pane open while the Yomitan-shaped visible marker clears.
ctx.state.hachidoriReaderSeen = true;
ctx.state.yomitanPopupVisible = false;
testGlobals.setHachidoriPaneOpen(true);
handlers.handleLookupWindowToggleRequested();
await wait(0);
assert.deepEqual(
testGlobals.commandEvents.filter(
(event) => event.type === 'setVisible' || event.type === 'clearActiveTextSource',
),
[{ type: 'setVisible', visible: false }, { type: 'clearActiveTextSource' }],
);
} finally {
ctx.state.keyboardDrivenModeEnabled = false;
testGlobals.restore();
}
});
test('configured subtitle-jump keybinding preserves pause when pause state is unknown', async () => {
const { handlers, testGlobals } = createKeyboardHandlerHarness();
+9 -3
View File
@@ -8,6 +8,7 @@ import {
HACHIDORI_HOST_SELECTOR,
YOMITAN_POPUP_COMMAND_EVENT,
YOMITAN_POPUP_HOST_SELECTOR,
isHachidoriPopupOpen,
isLookupPopupOpen,
isYomitanPopupVisible,
isYomitanPopupIframe,
@@ -749,10 +750,15 @@ export function createKeyboardHandlers(
triggerLookupForSelectedWord();
}
// Also clears Hachidori attention without an open pane, so callers like the
// Kiku modal opener leave no popup state behind.
// Closes any popup state: an open Hachidori pane (its attention may already be
// released) and attention without a pane, so callers like the Kiku modal
// opener leave nothing behind.
function closeLookupWindow(): boolean {
if (!ctx.state.yomitanPopupVisible && !isYomitanPopupVisible(document)) {
if (
!ctx.state.yomitanPopupVisible &&
!isYomitanPopupVisible(document) &&
!isHachidoriPopupOpen(document)
) {
return false;
}