fix(editor): restore the two </div>s that hid the entire timeline (blank editor in the 20260711 nightly) - #214
Conversation
The squash-merge resolutions that landed the sweep bar (#201) and the drum-pad strip (#199) each dropped their block's closing </div> at the canvas-wrap overlay anchor — the seam every chrome PR collides on. Since then #editor-canvas has been nested inside the HIDDEN drum-pad strip (itself inside the hidden sweep bar), so the canvas laid out at 0x0: chart and waveform invisible after every load and import, while the status bar reported the load and all 108 JS tests stayed green (nothing parses the markup). First tester-visible in the 20260711 nightly. Restores the two closers, byte-identical markup otherwise, and adds tests/screen_markup.test.mjs: a dependency-free tag-stack walk that fails if screen.html ever unbalances again, if #editor-canvas stops being a direct child of #editor-canvas-wrap, or if any canvas-wrap overlay becomes an ancestor instead of a sibling. Fails 3/3 on main. Verified end-to-end on the :8000 testbed via headless Chromium: before the fix the canvas had clientHeight 0 and the timeline was black; after, ruler + minimap + waveform + 1328 notes render. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EBQCHCNA81E9tHmSDHSe2Q
📝 WalkthroughWalkthroughTwo missing closing tags in ChangesEditor markup repair
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
tests/screen_markup.test.mjs (1)
56-56: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low valueSelf-closing detection can false-positive on trailing
/inside quoted attribute values.
/\/\s*$/.test(attrs)matches a trailing slash anywhere in the raw attrs string, including inside a quoted value (e.g.class="foo/"), not just an XHTML-style/>self-close. That would make the walker silently skip pushing such an element onto the stack instead of failing loudly — undermining the very guard this file exists to provide. Not currently triggered by screen.html's content, but worth hardening since this test is meant to catch future markup regressions.♻️ Suggested tightening
- if (VOID.has(name) || /\/\s*$/.test(attrs)) continue; + if (VOID.has(name) || /(?:^|[^"'])\/\s*$/.test(attrs)) continue;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/screen_markup.test.mjs` at line 56, Tighten the self-closing check in the markup walker around the VOID condition so it recognizes only an XHTML-style slash outside quoted attribute values, rather than any trailing slash in raw attrs. Preserve void-element handling and ensure elements with values such as class="foo/" remain on the stack so malformed markup is detected.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@tests/screen_markup.test.mjs`:
- Line 56: Tighten the self-closing check in the markup walker around the VOID
condition so it recognizes only an XHTML-style slash outside quoted attribute
values, rather than any trailing slash in raw attrs. Preserve void-element
handling and ensure elements with values such as class="foo/" remain on the
stack so malformed markup is detected.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 893b1ba9-cd52-4ba5-b2b3-4c3f7c906b02
📒 Files selected for processing (3)
CHANGELOG.mdscreen.htmltests/screen_markup.test.mjs
What broke
The editor timeline renders completely blank after any load or import — no ruler, no waveform, no notes — while the status bar reports the load normally. First tester-visible in the 20260711 nightly (the first build carrying the merged workspace-shell waves).
Root cause
Two closing
</div>s were lost at the canvas-wrap overlay anchor — the seam every chrome PR collides on — when the squash-merge resolutions for the sweep bar (#201) and the drum-pad strip (#199) landed (screen.htmlwas balanced at2ec753b, two closers short at1242631). Since then the DOM nests as:The canvas backing store still gets sized and painted (draw code reads the wrap), so nothing throws, every JS suite stays green (nothing parses the markup), and the status line says
Loaded:— but the element occupies zero layout.Fix + guard
tests/screen_markup.test.mjs: a dependency-free tag-stack walk overscreen.htmlthat fails if the file ever unbalances again, if#editor-canvasstops being a direct child of#editor-canvas-wrap, or if any canvas-wrap overlay becomes an ancestor instead of a sibling. Fails 3/3 on main, passes here — this seam is now guarded against the exact merge-resolution class that caused this.Verification
Driven end-to-end on the :8000 testbed with headless Chromium against a real feedpak:
#editor-canvasclientHeight: 0, parent chaincanvas → drum-pad-strip(hidden) → sweep-bar(hidden) → canvas-wrap, timeline black.clientHeight: 877, parent =canvas-wrap, ruler + minimap + waveform + 1328 notes render.Suggest merging ahead of the queue so the next nightly unbreaks testers.
🤖 Generated with Claude Code
https://claude.ai/code/session_01EBQCHCNA81E9tHmSDHSe2Q
Summary by CodeRabbit
Bug Fixes
Tests