player: fullscreen button (scales with the window)
'⛶ full' in the controls: native requestFullscreen on the video (it fills the viewport and rescales on window resize for free), with the iOS webkitEnterFullscreen fallback where the Fullscreen API doesn't exist. Click again to exit. Live browser test: enter + exit via the button.
This commit is contained in:
1 parent
379f591180
commit
cea04a20f6
2 files changed
+44
No files matched your search
@@ -446,6 +446,22 @@ async function showAnime(slug_id, opts = {}) {
|
|||||||
anB.classList.toggle("on", autoNext);
|
anB.classList.toggle("on", autoNext);
|
||||||
};
|
};
|
||||||
const ctl = [langBtn, spd, prevB, nextB, fillB, jump, anB];
|
const ctl = [langBtn, spd, prevB, nextB, fillB, jump, anB];
|
||||||
|
const fsB = el("button", "tiny", "\u26f6 full");
|
||||||
|
fsB.title = "fullscreen";
|
||||||
|
fsB.onclick = () => {
|
||||||
|
const v = document.querySelector("#player video");
|
||||||
|
if (!v) return;
|
||||||
|
if (document.fullscreenElement || document.webkitFullscreenElement) {
|
||||||
|
(document.exitFullscreen || document.webkitExitFullscreen).call(document);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// native Fullscreen API: the video fills the window (and scales with it);
|
||||||
|
// iOS Safari has no element fullscreen, so fall back to its in-player one
|
||||||
|
if (v.requestFullscreen) v.requestFullscreen();
|
||||||
|
else if (v.webkitEnterFullscreen) v.webkitEnterFullscreen();
|
||||||
|
else if (v.webkitRequestFullscreen) v.webkitRequestFullscreen();
|
||||||
|
};
|
||||||
|
ctl.push(fsB);
|
||||||
if (document.pictureInPictureEnabled) {
|
if (document.pictureInPictureEnabled) {
|
||||||
const pipB = el("button", "tiny", "\u29c9 PiP");
|
const pipB = el("button", "tiny", "\u29c9 PiP");
|
||||||
pipB.title = "picture-in-picture";
|
pipB.title = "picture-in-picture";
|
||||||
|
|||||||
@@ -490,3 +490,31 @@ async def _stale_history_remap_board():
|
|||||||
"location.search.includes('q=')", timeout=15000, polling=POLL)
|
"location.search.includes('q=')", timeout=15000, polling=POLL)
|
||||||
assert not errors, errors
|
assert not errors, errors
|
||||||
await browser.close()
|
await browser.close()
|
||||||
|
|
||||||
|
|
||||||
|
def test_fullscreen_toggle():
|
||||||
|
asyncio.run(_fullscreen_toggle())
|
||||||
|
|
||||||
|
|
||||||
|
async def _fullscreen_toggle():
|
||||||
|
# the player controls get a fullscreen button; in headless chromium the
|
||||||
|
# native API works, so exercise enter + exit.
|
||||||
|
async with async_playwright() as p:
|
||||||
|
browser = await p.chromium.launch(args=LAUNCH_ARGS)
|
||||||
|
page = await (await browser.new_context()).new_page()
|
||||||
|
errors = []
|
||||||
|
page.on("pageerror", lambda e: errors.append(str(e)))
|
||||||
|
await _login(page, "admin", "adminpw12345")
|
||||||
|
await page.goto(BASE + "/?anime=chainsaw-man-922")
|
||||||
|
btn = page.locator("button:has-text('full')")
|
||||||
|
await btn.wait_for(timeout=30000)
|
||||||
|
assert await page.evaluate(
|
||||||
|
"() => typeof document.querySelector('#player video').requestFullscreen === 'function'")
|
||||||
|
await btn.click(force=True)
|
||||||
|
await page.wait_for_function(
|
||||||
|
"() => !!document.fullscreenElement", timeout=15000, polling=POLL)
|
||||||
|
await btn.click(force=True)
|
||||||
|
await page.wait_for_function(
|
||||||
|
"() => !document.fullscreenElement", timeout=15000, polling=POLL)
|
||||||
|
assert not errors, errors
|
||||||
|
await browser.close()
|
||||||
Reference in new issue
Block a user