fix(showcase): break wn-breadcrumb slotchange infinite loop (WHYNOT-WP-0002 T11)
WnBreadcrumb._onSlot inserted separator <span>s into its own light DOM on slotchange but cleaned up in the shadow DOM, so they were never removed — each insertion re-fired slotchange, looping the main thread and wedging the showcase page. Made _onSlot idempotent: exclude own separators when reading items, and mutate only when separators are not already correct. - Un-fixme the showcase visual test; add a warm-up full-page capture so deviceScaleFactor-2 sub-pixel snapping settles before the assertion. All 5 visual tests pass. - Remove the dead Google-Fonts @import from colors_and_type.css (token stacks are system-ui; webfont unused + a CI-flake source; no visual change). - Unblocks WHYNOT-WP-0003 T08 (showcase = per-version visual catalog); both T11 and T08 marked done. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -216,11 +216,27 @@ gate that confirms Lit actually matches the designbook appearance.
|
||||
|
||||
```task
|
||||
id: WHYNOT-WP-0002-T11
|
||||
status: todo
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "7435338d-702a-43d7-9c86-49531fe0d8e4"
|
||||
```
|
||||
|
||||
**Resolved 2026-06-27.** Root cause: `WnBreadcrumb._onSlot` (`src/elements/layout.js`)
|
||||
inserted separator `<span>`s into its own **light DOM** on `slotchange`, but its
|
||||
cleanup queried the **shadow** wrapper for separators — so they were never removed.
|
||||
Each insertion mutated the breadcrumb's children, re-firing `slotchange`, inserting
|
||||
more separators, looping the main thread forever. (The earlier "specific demo
|
||||
composition" hypothesis was a misdiagnosis — the minimal repro simply omitted
|
||||
`<wn-breadcrumb>`; a minimal page *with* it reproduces the wedge, *without* it
|
||||
registers in ~300ms.) Fix: made `_onSlot` idempotent — it excludes its own
|
||||
separators when reading items and skips all DOM mutation once separators are
|
||||
already correct, so the self-triggered `slotchange` is a no-op and the loop ends.
|
||||
Also removed the dead Google-Fonts `@import` from `colors_and_type.css` (token
|
||||
font stacks are system-ui; the webfont was unused and a documented CI-flake source).
|
||||
`test.fixme` removed in `tests/visual/ui-kit.spec.mjs`; the showcase now renders and
|
||||
captures a stable `showcase.png` (a warm-up full-page capture settles deviceScaleFactor-2
|
||||
sub-pixel snapping before the assertion). All 5 visual tests pass.
|
||||
|
||||
Discovered 2026-06-26 while regenerating visual baselines after the T06 token
|
||||
regen. The `examples/showcase/index.html` "every component" page wedges the
|
||||
renderer main thread when its module executes — the page never reaches `load`
|
||||
|
||||
@@ -225,7 +225,7 @@ anything, complementing the machine-readable manifest.
|
||||
|
||||
```task
|
||||
id: WHYNOT-WP-0003-T08
|
||||
status: wait
|
||||
status: done
|
||||
priority: low
|
||||
state_hub_task_id: "a0886a4f-cf27-44ef-b8c6-8e61ceda1f84"
|
||||
```
|
||||
@@ -236,6 +236,13 @@ just to confirm, once T11 lands, that the showcase is deployable/inspectable per
|
||||
version (e.g. served from a tag) — no new build, reuse the existing page. Blocked on
|
||||
WP-0002-T11.
|
||||
|
||||
**Done 2026-06-27.** WP-0002-T11 landed (breadcrumb infinite-loop fixed); the
|
||||
showcase page now renders deterministically and is covered by a passing visual test
|
||||
(`showcase.png` baseline). No new build — the existing page *is* the per-version
|
||||
visual catalog: served statically from any checkout/tag (`pnpm showcase`), it pairs
|
||||
with the machine-readable `ir/manifest.json` + `ir/INDEX.md` as the visual side of a
|
||||
version's inventory. Nothing further to build.
|
||||
|
||||
---
|
||||
|
||||
## Phase 4 — Deferred: live contract-parity mode (design-only)
|
||||
|
||||
Reference in New Issue
Block a user