mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-09-22 17:16:19 -07:00
- Add backend selection, setup gating, Anki integration, and external host support - Add launcher flags, documentation, packaging, and focused tests - Open on-demand overlay modals on the first attempt
45 lines
1.4 KiB
JavaScript
45 lines
1.4 KiB
JavaScript
// Chrome MV3 lifecycle for the shared offscreen engine document.
|
|
// Firefox imports this shared module but never calls its guarded Chrome path.
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
import { extensionApi as chrome } from "./browser-api.js";
|
|
|
|
let creating = null;
|
|
|
|
export function chromeOffscreenSupported() {
|
|
return typeof chrome.runtime.getContexts === "function"
|
|
&& typeof chrome.offscreen?.createDocument === "function";
|
|
}
|
|
|
|
async function offscreenExists(url) {
|
|
const contexts = await chrome.runtime.getContexts({
|
|
contextTypes: ["OFFSCREEN_DOCUMENT"],
|
|
documentUrls: [chrome.runtime.getURL(url)],
|
|
});
|
|
return contexts.length > 0;
|
|
}
|
|
|
|
async function createOffscreen(url) {
|
|
try {
|
|
await chrome.offscreen.createDocument({
|
|
url,
|
|
reasons: ["DOM_SCRAPING", "AUDIO_PLAYBACK", "DISPLAY_MEDIA"],
|
|
justification:
|
|
"Runs the dictionary engine and pronunciation audio, and owns explicitly started local display capture across control-page closure.",
|
|
});
|
|
} catch (error) {
|
|
// Another extension context may have won the race; only a genuine absence
|
|
// is a failure.
|
|
if (!(await offscreenExists(url))) throw error;
|
|
} finally {
|
|
creating = null;
|
|
}
|
|
}
|
|
|
|
export async function ensureChromeOffscreen(url) {
|
|
if (!chromeOffscreenSupported()) return;
|
|
if (await offscreenExists(url)) return;
|
|
if (creating === null) creating = createOffscreen(url);
|
|
await creating;
|
|
}
|