// The context first: elements that register with it on connect need it to be // listening already when they upgrade. import './main-context.ts'; import './color-swatch-picker.ts'; import './hero-banner.ts'; import './labeled-field.ts'; import './secret-note.ts'; import './star-rating.ts'; // Components talk only through ; this file just reports on them. function $(tag: K, id: string): HTMLElementTagNameMap[K] { const el = document.querySelector(`${tag}#${id}`); if (!el) throw new Error(`missing <${tag} id="${id}">`); // oxlint-disable-next-line no-unsafe-type-assertion -- the tag in the selector guarantees it return el as HTMLElementTagNameMap[K]; } const rating = $('star-rating', 'rating'); const note = $('secret-note', 'note'); // --------------------------------------------------------------------------- // Closed vs open: what page code can see from outside. const probe = $('output', 'probe'); function updateProbe(): void { probe.textContent = [ `rating.shadowRoot → ${rating.shadowRoot ? 'ShadowRoot (open)' : 'null'}`, `note.shadowRoot → ${note.shadowRoot ? 'ShadowRoot' : 'null (closed)'}`, `note.revealed → ${note.revealed}`, `note.querySelector('p') → ${note.querySelector('p') ? '

' : 'null'}`, ].join('\n'); } updateProbe(); // --------------------------------------------------------------------------- // Attribute log: every reflected prop shows up here as an attribute mutation. const log = $('ol', 'log'); function show(value: string | null): string { return value === null ? '∅' : JSON.stringify(value); } const observer = new MutationObserver((records) => { for (const { target, attributeName, oldValue } of records) { if (!(target instanceof Element) || attributeName === null) continue; const element = document.createElement('code'); element.textContent = `<${target.localName}#${target.id}>`; const name = document.createElement('b'); name.textContent = attributeName; const change = `${show(oldValue)} → ${show(target.getAttribute(attributeName))}`; const item = document.createElement('li'); item.append(element, ' ', name, ' ', change); log.prepend(item); while (log.children.length > 40) log.lastElementChild?.remove(); } updateProbe(); }); for (const el of document.querySelectorAll('main-context [id]')) { if (el.localName.includes('-')) { observer.observe(el, { attributes: true, attributeOldValue: true }); } } $('button', 'clear-log').addEventListener('click', () => { log.replaceChildren(); });