90 lines
3.4 KiB
JavaScript
90 lines
3.4 KiB
JavaScript
// Generated, do not edit. sha256:2430e966fcc2cdaaba7ffd7cbd0b894b46925aefa4dabedcc39e93d69f099382
|
|
import { describe, it, afterEach } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { installDom } from '../helpers/mini-dom.mjs';
|
|
|
|
const dom = installDom();
|
|
const { openPopover, closePopover, isPopoverOpen } = await import('../../client/ui/popover.js');
|
|
|
|
const anchor = () => { const b = dom.document.createElement('button'); dom.document.body.appendChild(b); return b; };
|
|
const tick = () => new Promise(r => setTimeout(r, 0));
|
|
|
|
describe('openPopover', () => {
|
|
afterEach(() => closePopover());
|
|
|
|
it('appends one element with the class to the body and reports it open', () => {
|
|
const { el } = openPopover(anchor(), { className: 'popover new-menu' });
|
|
assert.equal(el.parentNode, dom.document.body);
|
|
assert.equal(el.className, 'popover new-menu');
|
|
assert.equal(isPopoverOpen(), true);
|
|
});
|
|
|
|
it('a second one closes the first, and calls its onClose', () => {
|
|
let closed = 0;
|
|
const first = openPopover(anchor(), { onClose: () => { closed++; } });
|
|
openPopover(anchor());
|
|
assert.equal(first.el.isConnected, false);
|
|
assert.equal(closed, 1);
|
|
assert.equal(dom.document.querySelectorAll('.popover').length, 1);
|
|
});
|
|
|
|
it('Escape closes it', () => {
|
|
const { el } = openPopover(anchor());
|
|
dom.key(dom.document.body, 'Escape');
|
|
assert.equal(el.isConnected, false);
|
|
assert.equal(isPopoverOpen(), false);
|
|
});
|
|
|
|
it('an outside click closes it, but only from the next tick; a click inside or on the anchor does not', async () => {
|
|
const a = anchor();
|
|
const { el } = openPopover(a);
|
|
el.innerHTML = '<span>in</span>';
|
|
dom.click(dom.document.body);
|
|
assert.equal(el.isConnected, true);
|
|
await tick();
|
|
dom.click(el.querySelector('span'));
|
|
dom.click(a);
|
|
assert.equal(el.isConnected, true);
|
|
dom.click(dom.document.body);
|
|
assert.equal(el.isConnected, false);
|
|
});
|
|
|
|
it('a popover closed within the same tick leaves no outside-click listener behind', async () => {
|
|
const before = dom.document.listeners.length;
|
|
openPopover(anchor());
|
|
closePopover();
|
|
await tick();
|
|
assert.equal(dom.document.listeners.length, before);
|
|
const { el } = openPopover(anchor());
|
|
el.innerHTML = '<span>in</span>';
|
|
await tick();
|
|
dom.click(el.querySelector('span'));
|
|
assert.equal(el.isConnected, true);
|
|
});
|
|
|
|
it('inside an open dialog it goes into the top overlay, not behind it in the body', () => {
|
|
const o1 = dom.document.createElement('div'); o1.className = 'dialog-overlay';
|
|
const o2 = dom.document.createElement('div'); o2.className = 'dialog-overlay';
|
|
dom.document.body.append(o1, o2);
|
|
const { el } = openPopover(anchor());
|
|
assert.equal(el.parentNode, o2);
|
|
o1.remove(); o2.remove();
|
|
});
|
|
|
|
it('position() keeps it inside the window', () => {
|
|
const a = anchor();
|
|
a.getBoundingClientRect = () => ({ left: 1270, top: 790, right: 1280, bottom: 800, width: 10, height: 10 });
|
|
const { el, position } = openPopover(a);
|
|
Object.defineProperty(el, 'offsetWidth', { value: 200 });
|
|
Object.defineProperty(el, 'offsetHeight', { value: 100 });
|
|
position();
|
|
assert.equal(el.style.left, `${1280 - 8 - 200}px`);
|
|
assert.equal(el.style.top, `${790 - 100 - 6}px`);
|
|
});
|
|
|
|
it('closePopover without one open does nothing', () => {
|
|
closePopover();
|
|
assert.equal(isPopoverOpen(), false);
|
|
});
|
|
});
|