Click the sky, get the sky: ~2.5x, centred, over a dimmed backdrop. Esc or a click closes it. Enlarges the real element rather than mirroring it. I built the mirror first and it rendered black — THE SCREEN is a WebGL canvas, and drawImage from a WebGL context without preserveDrawingBuffer returns nothing. Asking LANE-SCREEN to enable that flag would cost them a buffer copy every frame for a feature used occasionally. Since that means touching another lane's element, it snapshots the style attribute on open and restores it verbatim on close — including the case where SCREEN later adds inline styles of their own, which is tested. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
81 lines
2.7 KiB
TypeScript
81 lines
2.7 KiB
TypeScript
// @vitest-environment happy-dom
|
|
import { describe, expect, it } from 'vitest';
|
|
import { createScreenView } from './screenview';
|
|
|
|
function mount(withInlineStyle = false) {
|
|
document.body.innerHTML = withInlineStyle
|
|
? '<canvas id="screen" style="position:fixed;top:10px"></canvas>'
|
|
: '<canvas id="screen"></canvas>';
|
|
const source = document.getElementById('screen') as HTMLCanvasElement;
|
|
const view = createScreenView(source);
|
|
document.body.append(view.el);
|
|
return { view, source };
|
|
}
|
|
|
|
const click = (el: Element) => el.dispatchEvent(new MouseEvent('pointerdown', { bubbles: true }));
|
|
|
|
describe('THE SCREEN click-to-enlarge', () => {
|
|
it('starts closed and leaves THE SCREEN alone', () => {
|
|
const { view, source } = mount();
|
|
expect(view.isOpen()).toBe(false);
|
|
expect(source.getAttribute('style')).toBeNull();
|
|
});
|
|
|
|
it('enlarges THE SCREEN and dims the backdrop when clicked', () => {
|
|
const { view, source } = mount();
|
|
click(source);
|
|
expect(view.isOpen()).toBe(true);
|
|
expect(view.el.classList.contains('is-open')).toBe(true);
|
|
const style = source.getAttribute('style')!;
|
|
expect(style).toContain('position:fixed');
|
|
expect(style).toContain('z-index:41'); // above the backdrop
|
|
});
|
|
|
|
it('restores THE SCREEN exactly as it found it', () => {
|
|
// Another lane owns this element; we must hand it back untouched.
|
|
const { view, source } = mount();
|
|
click(source);
|
|
view.close();
|
|
expect(source.getAttribute('style')).toBeNull();
|
|
expect(view.isOpen()).toBe(false);
|
|
});
|
|
|
|
it('preserves inline styles LANE-SCREEN may add later', () => {
|
|
const { view, source } = mount(true);
|
|
const before = source.getAttribute('style');
|
|
click(source);
|
|
expect(source.getAttribute('style')).toContain('top:10px'); // ours appended, not replacing
|
|
view.close();
|
|
expect(source.getAttribute('style')).toBe(before);
|
|
});
|
|
|
|
it('closes when the enlarged SCREEN is clicked again', () => {
|
|
const { view, source } = mount();
|
|
click(source);
|
|
click(source);
|
|
expect(view.isOpen()).toBe(false);
|
|
expect(source.getAttribute('style')).toBeNull();
|
|
});
|
|
|
|
it('closes on a click on the dimmed backdrop', () => {
|
|
const { view, source } = mount();
|
|
click(source);
|
|
click(view.el);
|
|
expect(view.isOpen()).toBe(false);
|
|
});
|
|
|
|
it('close() is idempotent and does not clobber the style on a second call', () => {
|
|
const { view, source } = mount(true);
|
|
const before = source.getAttribute('style');
|
|
view.close();
|
|
view.close();
|
|
expect(source.getAttribute('style')).toBe(before);
|
|
});
|
|
|
|
it('survives having no SCREEN to enlarge', () => {
|
|
document.body.innerHTML = '';
|
|
const view = createScreenView(null);
|
|
expect(() => { view.toggle(); view.close(); }).not.toThrow();
|
|
});
|
|
});
|