mirror of
https://github.com/Matysh/houseplan-card
synced 2026-07-31 08:28:31 +00:00
- outlineWithout trims the rooms' solid strokes under open stretches (.room.noedge kills the polygon stroke incl. hover; trimmed .room-outline path draws the remaining walls) - dash color follows the space stroke color; openwalls layer moved after the glow layer - +1 unit test (105); smoke_openwall extended; docs same-commit
62 lines
3.6 KiB
JavaScript
62 lines
3.6 KiB
JavaScript
import { launch } from './serve.mjs';
|
|
const { page, browser } = await launch();
|
|
const res = await page.evaluate(async () => {
|
|
const out = {};
|
|
const c = window.__card;
|
|
const sr = () => c.shadowRoot || c.renderRoot;
|
|
c._setMode('plan'); c._tool = 'openwall'; await c.updateComplete;
|
|
// r1|r2 делят стену x=0.55 → клик по ней открывает границу
|
|
const H = 1000 / (c._curSpaceCfg.aspect || 1);
|
|
c._openWallClick([550, 0.25 * H]);
|
|
await c.updateComplete;
|
|
const r1 = c._curSpaceCfg.rooms.find((r) => r.id === 'r1');
|
|
const r2 = c._curSpaceCfg.rooms.find((r) => r.id === 'r2');
|
|
out.linked = (r1.open_to || []).includes('r2') && (r2.open_to || []).includes('r1');
|
|
// пунктир отрисован
|
|
out.dashes = sr().querySelectorAll('.openwall').length > 0;
|
|
out.hotClass = !!sr().querySelector('.openwalls.hot');
|
|
// в Просмотре: сплошной штрих комнаты снят, контур без выреза + пунктир ПОВЕРХ glow
|
|
c._setMode('view'); await c.updateComplete;
|
|
out.noedge = sr().querySelectorAll('.room.noedge').length >= 2;
|
|
out.trimmedOutline = sr().querySelectorAll('.room-outline').length >= 2;
|
|
const svgEl = sr().querySelector('svg');
|
|
const order = [...svgEl.children].map((el) => el.classList?.[0] || el.tagName);
|
|
const gi = order.indexOf('glowlayer');
|
|
const oi = order.indexOf('openwalls');
|
|
out.dashAboveGlow = gi === -1 || oi > gi;
|
|
c._setMode('plan'); c._tool = 'openwall'; await c.updateComplete;
|
|
// повторный клик закрывает
|
|
c._openWallClick([550, 0.25 * H]); await c.updateComplete;
|
|
out.toggledOff = !(c._curSpaceCfg.rooms.find((r) => r.id === 'r1').open_to || []).includes('r2');
|
|
out.dashesGone = sr().querySelectorAll('.openwall').length === 0;
|
|
// клик мимо стен — тост, без изменений
|
|
c._openWallClick([100, 100]);
|
|
out.missToast = !!c._toast;
|
|
// снова открыть для glow-теста
|
|
c._openWallClick([550, 0.25 * H]); await c.updateComplete;
|
|
// glow: свет из r1 заливает и r2 (clip содержит оба полигона)
|
|
c._setMode('view'); await c.updateComplete;
|
|
c._serverCfg = { ...c._serverCfg, spaces: c._serverCfg.spaces.map((s) => s.id !== c._space ? s : ({
|
|
...s, settings: { ...(s.settings || {}), fill_mode: 'glow' } })) };
|
|
const litLight = c._devices.find((d) => d.space === c._space && d.entities.some((e) => e.startsWith('light.') && c.hass.states[e]?.state === 'on'));
|
|
const c1 = c._roomCenter(c._spaceModel().rooms.find((r) => r.id === 'r1'));
|
|
const aspect = c._curSpaceCfg.aspect || 1;
|
|
c._layout = { ...c._layout, [litLight.id]: { s: c._space, x: c1[0] / 1000, y: c1[1] / (1000 / aspect) } };
|
|
c.requestUpdate(); await c.updateComplete;
|
|
const clip = sr().querySelector('defs clipPath[id^="hp-glowclip"]');
|
|
out.zoneClip = clip ? clip.querySelectorAll('path').length >= 2 : false;
|
|
// транзитивность: r2↔r3 тоже открыть → clip получит 3 полигона
|
|
const rr2 = c._curSpaceCfg.rooms.find((r) => r.id === 'r2');
|
|
const rr3 = c._curSpaceCfg.rooms.find((r) => r.id === 'r3');
|
|
if (rr3) {
|
|
rr2.open_to = [...(rr2.open_to || []), 'r3'];
|
|
rr3.open_to = [...(rr3.open_to || []), 'r2'];
|
|
c._regSignature = ''; c.requestUpdate(); await c.updateComplete;
|
|
const clip2 = sr().querySelector('defs clipPath[id^="hp-glowclip"]');
|
|
out.transitive = clip2 ? clip2.querySelectorAll('path').length >= 3 : false;
|
|
} else out.transitive = 'no r3';
|
|
return out;
|
|
});
|
|
console.log(JSON.stringify(res, null, 1));
|
|
await browser.close();
|