fix bla
This commit is contained in:
@@ -103,14 +103,17 @@ export class FirefoxController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Rappelle le plein écran, puis le vérifie.
|
||||
* Rappelle le plein écran en envoyant la touche du lecteur, et seulement elle.
|
||||
*
|
||||
* Deux tentatives, dans cet ordre volontaire. La touche d'abord : c'est le
|
||||
* geste de l'opérateur, elle passe par le gestionnaire du lecteur et donne
|
||||
* exactement le cadrage attendu par le site. L'appel direct à
|
||||
* `requestFullscreen` ensuite, seulement si la première n'a rien produit —
|
||||
* il fonctionne toujours mais met en plein écran l'élément vidéo brut, sans
|
||||
* l'habillage du lecteur.
|
||||
* Volontairement une seule voie, sans repli. Une version antérieure appelait
|
||||
* `requestFullscreen()` sur l'élément vidéo brut quand la touche ne semblait
|
||||
* pas avoir agi — mais « ne semblait pas » se mesurait à
|
||||
* `document.fullscreenElement`, qui ne dit rien du bouton « théâtre » de
|
||||
* Stripchat : ce mode-là garde la barre du haut visible et n'a souvent rien
|
||||
* à voir avec l'API plein écran native du navigateur. Le repli déclenchait
|
||||
* alors un vrai plein écran natif — vidéo seule, tout le reste disparu —
|
||||
* précisément l'effet que la touche du lecteur, elle, évite. Mieux vaut
|
||||
* envoyer le geste attendu par le site et ne pas le corriger à l'aveugle.
|
||||
*/
|
||||
async restoreFullscreen(settings: FullscreenSettings): Promise<FullscreenOutcome> {
|
||||
await this.ensureReady();
|
||||
@@ -139,57 +142,18 @@ export class FirefoxController {
|
||||
// Le passage en plein écran est animé : relire trop tôt renverrait faux
|
||||
// alors que la touche a bien été prise en compte.
|
||||
await delay(1200);
|
||||
if (await this.isFullscreen()) {
|
||||
this.fullscreen = true;
|
||||
return { method: 'webdriver (touche)', target: this.url ?? undefined, confirmed: true };
|
||||
}
|
||||
|
||||
this.log(
|
||||
'info',
|
||||
`La touche « ${settings.key} » n'a pas basculé la page ; tentative directe sur l'élément vidéo`,
|
||||
);
|
||||
const detail = await this.requestFullscreenOnVideo();
|
||||
await delay(800);
|
||||
const confirmed = await this.isFullscreen();
|
||||
|
||||
this.fullscreen = confirmed;
|
||||
if (confirmed) {
|
||||
return { method: 'webdriver (élément vidéo)', target: this.url ?? undefined, confirmed };
|
||||
}
|
||||
|
||||
// « Fullscreen request denied » ne dit rien à personne. Les trois conditions
|
||||
// que Gecko exige sont lisibles depuis la page : on les relit pour nommer
|
||||
// celle qui manque, plutôt que de laisser l'opérateur deviner.
|
||||
const why = await this.explainRefusal(detail);
|
||||
this.lastError = why;
|
||||
return { method: `webdriver — ${why}`, target: this.url ?? undefined, confirmed: false };
|
||||
}
|
||||
|
||||
/**
|
||||
* Nomme la condition manquante après un refus de plein écran.
|
||||
*
|
||||
* Le focus est de loin la première cause : Firefox refuse le plein écran à un
|
||||
* document dont la fenêtre n'est pas celle qu'a sélectionnée le gestionnaire
|
||||
* de fenêtres — et sur une VM, il suffit qu'OBS ou un terminal l'ait pris.
|
||||
*/
|
||||
private async explainRefusal(detail: string): Promise<string> {
|
||||
const raw = await this.evaluate(
|
||||
'JSON.stringify({ focus: document.hasFocus(), api: document.fullscreenEnabled, video: !!document.querySelector("video") })',
|
||||
).catch(() => null);
|
||||
|
||||
const page = typeof raw === 'string' ? (JSON.parse(raw) as Record<string, boolean>) : null;
|
||||
if (!page) return detail;
|
||||
|
||||
if (!page.video) return 'aucun élément vidéo dans la page — le lecteur a-t-il fini de charger ?';
|
||||
if (!page.focus) {
|
||||
return (
|
||||
"la fenêtre Firefox n'a pas le focus : Firefox refuse le plein écran à un onglet " +
|
||||
"en arrière-plan. Ferme les autres fenêtres de la session, ou laisse Firefox seul " +
|
||||
"au premier plan sur cette VM"
|
||||
);
|
||||
}
|
||||
if (!page.api) return "l'API plein écran est désactivée dans ce profil Firefox";
|
||||
return detail;
|
||||
// `confirmed` reste `undefined`, pas `false`, quand l'API native ne signale
|
||||
// rien : c'est le cas attendu pour un mode « théâtre » propre au site, pas
|
||||
// un échec. Le distinguer évite de journaliser en avertissement une touche
|
||||
// qui a très bien pu faire son effet.
|
||||
return {
|
||||
method: 'webdriver (touche)',
|
||||
target: this.url ?? undefined,
|
||||
confirmed: confirmed ? true : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
/** Décharge le lecteur sans détruire la fenêtre — donc sans casser la source OBS. */
|
||||
@@ -494,30 +458,6 @@ export class FirefoxController {
|
||||
return result === true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Demande le plein écran sur l'élément vidéo.
|
||||
*
|
||||
* `userActivation` fait croire à Firefox à un geste utilisateur : sans lui,
|
||||
* l'API refuse l'appel. Le profil pose aussi
|
||||
* `full-screen-api.allow-trusted-requests-only=false`, pour les versions de
|
||||
* Firefox qui ne connaissent pas encore ce paramètre de commande.
|
||||
*/
|
||||
private async requestFullscreenOnVideo(): Promise<string> {
|
||||
const expression = `(async () => {
|
||||
const video = document.querySelector('video');
|
||||
if (!video) return 'aucune vidéo dans la page';
|
||||
try {
|
||||
await (video.requestFullscreen ? video.requestFullscreen() : Promise.reject(new Error('API absente')));
|
||||
return 'ok';
|
||||
} catch (err) {
|
||||
return 'refus : ' + (err && err.message ? err.message : err);
|
||||
}
|
||||
})()`;
|
||||
|
||||
const result = await this.evaluate(expression, true).catch((err: Error) => err.message);
|
||||
return typeof result === 'string' ? result : 'ok';
|
||||
}
|
||||
|
||||
private async evaluate(expression: string, userActivation = false): Promise<unknown> {
|
||||
const response = await this.send<{
|
||||
type: string;
|
||||
|
||||
Reference in New Issue
Block a user