A game is easier to judge and to play without the editor around it. The Game tab and the game link now both have a button that puts the game view itself into fullscreen, not just the browser window. - The Game tab header has a fullscreen button on the right. It hides toolbar, panels, tab headers and console and keeps the zoom from the picker. A running game keeps running. - A corner button at the top right, or Esc, leaves fullscreen and puts the view back into the tab where it was. - The game link shows the same corner button. Over a running game it hides after 2 s without mouse movement and returns on the next move. - A click on the corner button never reaches the game. - Stop ends fullscreen. Stop switches back to the Scene tab, and any switch away from the Game tab ends fullscreen, so no empty screen is left behind. - src/viewport/fullscreen.ts wraps the Fullscreen API and holds the rule for when the button shows. FullscreenCorner.ts is the button used by both pages. Two SVG icons are new. - Editor.showGameFullscreen moves the GameViewport into the root while fullscreen is on. Tests: - ./check.sh: 195 files, 2815 tests, exit 0 (3 new unit tests). - e2e 60: 2 new checks for the corner button on the game link. - e2e 61 (new): 4 checks for fullscreen in the editor. - Full e2e run (local): ALL PASSED, 1580 checks. - Counter-checks fail as expected: rule without "no game running", no stopPropagation (60h), no end on tab switch (61c), no reparenting of the view (61a). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
65 lines
2.3 KiB
JavaScript
65 lines
2.3 KiB
JavaScript
/**
|
||
* Fullscreen of the game tab (#267): the button in its header puts the game view on its own into
|
||
* fullscreen – no toolbar, no panels, no header –, the game keeps running, and the button in the
|
||
* corner puts the view back under its header. Stopping the game from fullscreen ends it as well.
|
||
*/
|
||
export async function fullscreen(t) {
|
||
const { check, json, click, sleep, play, stop, shot, press, exceptions } = t;
|
||
const info = async () => ({
|
||
...(await json('__gm.gameFullscreen()')),
|
||
view: (await json('__gm.gameScale()')).view,
|
||
});
|
||
const size = { w: await json('innerWidth'), h: await json('innerHeight') };
|
||
|
||
await press('Escape');
|
||
await play();
|
||
const windowed = await info();
|
||
|
||
// 61a. The header button: the game view alone fills the page, and the game goes on.
|
||
await click(windowed.headerButton.x, windowed.headerButton.y);
|
||
await sleep(500);
|
||
const full = { ...(await info()), mode: await json('__gm.state.mode') };
|
||
check(
|
||
'the header button puts the running game view alone into fullscreen',
|
||
windowed.view.y > 0 &&
|
||
full.on &&
|
||
full.document &&
|
||
full.headerButton === null &&
|
||
full.view.x === 0 &&
|
||
full.view.y === 0 &&
|
||
full.view.w === size.w &&
|
||
full.view.h === size.h &&
|
||
full.mode === 'play',
|
||
JSON.stringify({ size, windowed, full }),
|
||
);
|
||
await shot('61-fullscreen');
|
||
|
||
// 61b. The corner button leaves it, and the view is back under its header, as big as before.
|
||
if (full.corner) await click(full.corner.x, full.corner.y);
|
||
await sleep(500);
|
||
const back = await info();
|
||
check(
|
||
'the corner button leaves fullscreen and puts the view back in its tab',
|
||
full.corner !== null &&
|
||
!back.on &&
|
||
!back.document &&
|
||
back.headerButton !== null &&
|
||
JSON.stringify(back.view) === JSON.stringify(windowed.view),
|
||
JSON.stringify({ corner: full.corner, back }),
|
||
);
|
||
|
||
// 61c. Stop goes back to the scene tab, which ends fullscreen too.
|
||
await click(back.headerButton.x, back.headerButton.y);
|
||
await sleep(500);
|
||
const again = await info();
|
||
await stop();
|
||
await sleep(300);
|
||
const stopped = await info();
|
||
check(
|
||
'stopping the game from fullscreen ends fullscreen',
|
||
again.on && !stopped.on && !stopped.document,
|
||
JSON.stringify({ again: again.on, stopped }),
|
||
);
|
||
check('fullscreen threw nothing', exceptions().length === 0, exceptions().join(' | '));
|
||
}
|