mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-10-20 17:01:24 -07:00
fix(hachidori): treat only an open pane as an open popup for lookup controls
This commit is contained in:
2 files changed
+38
-12
No files matched your search
@@ -1288,6 +1288,31 @@ test('Hachidori attention without an open popup pane still forwards imported mpv
|
||||
}
|
||||
});
|
||||
|
||||
test('keyboard mode: lookup toggle opens a lookup during Hachidori attention without a pane', async () => {
|
||||
const { ctx, handlers, testGlobals } = createKeyboardHandlerHarness();
|
||||
|
||||
try {
|
||||
await handlers.setupMpvInputForwarding();
|
||||
handlers.handleKeyboardModeToggleRequested();
|
||||
ctx.state.keyboardSelectedWordIndex = 1;
|
||||
handlers.syncKeyboardTokenSelection();
|
||||
ctx.state.hachidoriReaderSeen = true;
|
||||
ctx.state.yomitanPopupVisible = true;
|
||||
|
||||
handlers.handleLookupWindowToggleRequested();
|
||||
await wait(0);
|
||||
|
||||
assert.equal(ctx.dom.subtitleRoot.classList.contains('has-selection'), true);
|
||||
assert.deepEqual(
|
||||
testGlobals.commandEvents.filter((event) => event.type === 'setVisible'),
|
||||
[],
|
||||
);
|
||||
} finally {
|
||||
ctx.state.keyboardDrivenModeEnabled = false;
|
||||
testGlobals.restore();
|
||||
}
|
||||
});
|
||||
|
||||
test('configured subtitle-jump keybinding preserves pause when pause state is unknown', async () => {
|
||||
const { handlers, testGlobals } = createKeyboardHandlerHarness();
|
||||
|
||||
|
||||
@@ -520,8 +520,7 @@ export function createKeyboardHandlers(
|
||||
pendingSelectionAnchorAfterSubtitleSeek = null;
|
||||
resetSelectionToStartOnNextSubtitleSync = false;
|
||||
const shouldRefreshLookup =
|
||||
pendingLookupRefreshAfterSubtitleSeek &&
|
||||
(ctx.state.yomitanPopupVisible || isYomitanPopupVisible(document));
|
||||
pendingLookupRefreshAfterSubtitleSeek && isLookupPopupOpen(ctx.state, document);
|
||||
pendingLookupRefreshAfterSubtitleSeek = false;
|
||||
if (shouldRefreshLookup) {
|
||||
queueMicrotask(() => {
|
||||
@@ -713,7 +712,7 @@ export function createKeyboardHandlers(
|
||||
if (lookupScanFallbackTimer !== null) clearTimeout(lookupScanFallbackTimer);
|
||||
lookupScanFallbackTimer = setTimeout(() => {
|
||||
lookupScanFallbackTimer = null;
|
||||
if (ctx.state.yomitanPopupVisible || isYomitanPopupVisible(document)) {
|
||||
if (isLookupPopupOpen(ctx.state, document)) {
|
||||
return;
|
||||
}
|
||||
// Dispatch directly on the selected token span; when overlay pointer-events are disabled,
|
||||
@@ -743,13 +742,15 @@ export function createKeyboardHandlers(
|
||||
}
|
||||
|
||||
function handleLookupWindowToggleRequested(): void {
|
||||
if (ctx.state.yomitanPopupVisible || isYomitanPopupVisible(document)) {
|
||||
if (isLookupPopupOpen(ctx.state, document)) {
|
||||
closeLookupWindow();
|
||||
return;
|
||||
}
|
||||
triggerLookupForSelectedWord();
|
||||
}
|
||||
|
||||
// Also clears Hachidori attention without an open pane, so callers like the
|
||||
// Kiku modal opener leave no popup state behind.
|
||||
function closeLookupWindow(): boolean {
|
||||
if (!ctx.state.yomitanPopupVisible && !isYomitanPopupVisible(document)) {
|
||||
return false;
|
||||
@@ -775,7 +776,7 @@ export function createKeyboardHandlers(
|
||||
return false;
|
||||
}
|
||||
|
||||
const popupVisible = ctx.state.yomitanPopupVisible || isYomitanPopupVisible(document);
|
||||
const popupVisible = isLookupPopupOpen(ctx.state, document);
|
||||
const result = moveKeyboardSelection(delta);
|
||||
if (result === 'no-words') {
|
||||
seekAdjacentSubtitleAndQueueSelection(delta, popupVisible);
|
||||
@@ -796,7 +797,7 @@ export function createKeyboardHandlers(
|
||||
code: string,
|
||||
repeat: boolean = true,
|
||||
): boolean {
|
||||
if (!ctx.state.yomitanPopupVisible && !isYomitanPopupVisible(document)) {
|
||||
if (!isLookupPopupOpen(ctx.state, document)) {
|
||||
return false;
|
||||
}
|
||||
dispatchYomitanPopupKeydown(key, code, [], repeat);
|
||||
@@ -804,7 +805,7 @@ export function createKeyboardHandlers(
|
||||
}
|
||||
|
||||
function mineSelectedFromController(): boolean {
|
||||
if (!ctx.state.yomitanPopupVisible && !isYomitanPopupVisible(document)) {
|
||||
if (!isLookupPopupOpen(ctx.state, document)) {
|
||||
return false;
|
||||
}
|
||||
dispatchYomitanPopupMineSelected();
|
||||
@@ -812,7 +813,7 @@ export function createKeyboardHandlers(
|
||||
}
|
||||
|
||||
function cyclePopupAudioSourceForController(direction: -1 | 1): boolean {
|
||||
if (!ctx.state.yomitanPopupVisible && !isYomitanPopupVisible(document)) {
|
||||
if (!isLookupPopupOpen(ctx.state, document)) {
|
||||
return false;
|
||||
}
|
||||
dispatchYomitanPopupCycleAudioSource(direction);
|
||||
@@ -820,7 +821,7 @@ export function createKeyboardHandlers(
|
||||
}
|
||||
|
||||
function playCurrentAudioForController(): boolean {
|
||||
if (!ctx.state.yomitanPopupVisible && !isYomitanPopupVisible(document)) {
|
||||
if (!isLookupPopupOpen(ctx.state, document)) {
|
||||
return false;
|
||||
}
|
||||
dispatchYomitanPopupPlayCurrentAudio();
|
||||
@@ -828,7 +829,7 @@ export function createKeyboardHandlers(
|
||||
}
|
||||
|
||||
function scrollPopupByController(deltaX: number, deltaY: number): boolean {
|
||||
if (!ctx.state.yomitanPopupVisible && !isYomitanPopupVisible(document)) {
|
||||
if (!isLookupPopupOpen(ctx.state, document)) {
|
||||
return false;
|
||||
}
|
||||
dispatchYomitanPopupScrollBy(deltaX, deltaY);
|
||||
@@ -855,7 +856,7 @@ export function createKeyboardHandlers(
|
||||
if (!ctx.state.keyboardDrivenModeEnabled) {
|
||||
return;
|
||||
}
|
||||
if (!ctx.state.yomitanPopupVisible && !isYomitanPopupVisible(document)) {
|
||||
if (!isLookupPopupOpen(ctx.state, document)) {
|
||||
return;
|
||||
}
|
||||
restoreOverlayKeyboardFocus();
|
||||
@@ -900,7 +901,7 @@ export function createKeyboardHandlers(
|
||||
}
|
||||
|
||||
const key = e.code;
|
||||
const popupVisible = ctx.state.yomitanPopupVisible || isYomitanPopupVisible(document);
|
||||
const popupVisible = isLookupPopupOpen(ctx.state, document);
|
||||
if (key === 'ArrowLeft' || key === 'KeyH') {
|
||||
const result = moveKeyboardSelection(-1);
|
||||
if (result === 'start-boundary' || result === 'no-words') {
|
||||
|
||||
Reference in new issue
Block a user