mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-11-11 04:46:07 -08:00
fix(overlay): keep popup pause working with Hachidori 0.4.0
Hachidori 0.4.0 closed its popup shadow root, so isHachidoriPopupOpen always returned false. The popup never took over the subtitle hover pause, and moving off the subtitle resumed playback with the popup open. Popup key and controller routing read the same check. The sidebar kept working because its hold follows the attention event instead of the pane. The fork now publishes the pane state on the host element, and the renderer reads that attribute instead of upstream's shadow root and CSS class. The unit stubs modelled an open root and hid this, so test:dictionary:electron now drives the real reader and asserts the attribute follows the pane.
This commit is contained in:
5 files changed
+95
-30
No files matched your search
@@ -5,9 +5,8 @@ import { SUBTITLE_DEFAULT_CONFIG } from '../../config/definitions/defaults-subti
|
||||
import { createRendererState } from '../state';
|
||||
import { createMouseHandlers } from './mouse.js';
|
||||
import {
|
||||
HACHIDORI_HOST_SELECTOR,
|
||||
HACHIDORI_POPUP_HIDDEN_EVENT,
|
||||
HACHIDORI_POPUP_SELECTOR,
|
||||
HACHIDORI_POPUP_OPEN_SELECTOR,
|
||||
HACHIDORI_POPUP_SHOWN_EVENT,
|
||||
YOMITAN_LOOKUP_EVENT,
|
||||
YOMITAN_POPUP_HIDDEN_EVENT,
|
||||
@@ -110,23 +109,11 @@ function createMouseHarness(
|
||||
};
|
||||
const ignoreCalls: IgnoreCall[] = [];
|
||||
const mpvCommands: Array<(string | number)[]> = [];
|
||||
const popupPane = {
|
||||
get hidden() {
|
||||
return !harness.popupPaneOpen;
|
||||
},
|
||||
};
|
||||
const popupHost = {
|
||||
tagName: options.hachidori ? 'HACHIDORI-HOST' : 'DIV',
|
||||
getAttribute: (name: string) =>
|
||||
name === 'data-subminer-yomitan-popup-visible' ? String(harness.popupHostVisible) : null,
|
||||
shadowRoot: {
|
||||
querySelectorAll: (selector: string) =>
|
||||
selector === HACHIDORI_POPUP_SELECTOR ? [popupPane] : [],
|
||||
},
|
||||
};
|
||||
const hostSelectors = options.hachidori
|
||||
? [HACHIDORI_HOST_SELECTOR, YOMITAN_POPUP_HOST_SELECTOR]
|
||||
: [YOMITAN_POPUP_HOST_SELECTOR];
|
||||
|
||||
const harness = {
|
||||
ctx,
|
||||
@@ -183,7 +170,10 @@ function createMouseHarness(
|
||||
if (selector === YOMITAN_POPUP_VISIBLE_HOST_SELECTOR) {
|
||||
return harness.popupHostVisible ? [popupHost] : [];
|
||||
}
|
||||
return hostSelectors.includes(selector) &&
|
||||
if (selector === HACHIDORI_POPUP_OPEN_SELECTOR) {
|
||||
return harness.popupPaneOpen ? [popupHost] : [];
|
||||
}
|
||||
return selector === YOMITAN_POPUP_HOST_SELECTOR &&
|
||||
(harness.popupHostVisible || harness.popupHostAttached)
|
||||
? [popupHost]
|
||||
: [];
|
||||
@@ -529,6 +519,31 @@ test('Hachidori hover popup pauses when shown', async (t) => {
|
||||
assert.deepEqual(h.mpvCommands, [PAUSE]);
|
||||
});
|
||||
|
||||
test('leaving the subtitle keeps playback paused while a Hachidori popup is open', async (t) => {
|
||||
let paused = false;
|
||||
const h = createMouseHarness(t, {
|
||||
hoverPause: true,
|
||||
popupPause: true,
|
||||
hachidori: true,
|
||||
getPlaybackPaused: async () => paused,
|
||||
});
|
||||
h.handlers.setupYomitanObserver();
|
||||
|
||||
await h.handlers.handleMouseEnter();
|
||||
paused = true;
|
||||
h.popupPaneOpen = true;
|
||||
h.popupHostVisible = true;
|
||||
h.fire('window', HACHIDORI_POPUP_SHOWN_EVENT);
|
||||
await waitForNextTick();
|
||||
await h.handlers.handleMouseLeave();
|
||||
assert.deepEqual(h.mpvCommands, [PAUSE]);
|
||||
|
||||
h.popupPaneOpen = false;
|
||||
h.popupHostVisible = false;
|
||||
h.fire('window', HACHIDORI_POPUP_HIDDEN_EVENT);
|
||||
assert.deepEqual(h.mpvCommands, [PAUSE, RESUME]);
|
||||
});
|
||||
|
||||
test('popup shown reclaims overlay focus on macOS and captures click-away', (t) => {
|
||||
const h = createMouseHarness(t, { platform: 'macos' });
|
||||
h.handlers.setupYomitanObserver();
|
||||
|
||||
Reference in new issue
Block a user