better toolbar

This commit is contained in:
Your Name 2026-10-01 00:11:16 -04:00
parent 2f1c9b9c02
commit 5fb04f6a7d
6 changed files with 433 additions and 87 deletions

View file

@ -185,7 +185,7 @@ const PROBE = `(() => {
w: c.width, h: c.height, drawn, tones: [...tones].length, toneSet: [...tones],
cx: drawn ? cx / drawn : null, cy: drawn ? cy / drawn : null,
hash: h >>> 0,
frame: document.querySelector('.time .pane-head .dim')?.textContent ?? '',
frame: document.querySelector('.time .pane-head .at-frame')?.textContent ?? '',
// What the top bar says about the document. The media pool holds the OPEN
// document's library now and no longer names documents at all, so the status
// line is the page's own answer to "what am I looking at".
@ -202,7 +202,7 @@ const PROBE = `(() => {
// knows which frame it wants, not how long the clip it is looking at happens to
// be, and reading it here is one place instead of every call site.
const SEEK = (f) => `(() => {
const read = document.querySelector('.time .pane-head .dim').textContent;
const read = document.querySelector('.time .pane-head .at-frame').textContent;
// Split, not a regex: this is inside a template literal, where an escaped
// slash collapses to a bare one and the two together open a line comment that
// eats the rest of the statement. The readout is "12 / 229" and nothing else.
@ -216,7 +216,7 @@ const SEEK = (f) => `(() => {
clientY: box.top + box.height / 2,
}));
ruler.dispatchEvent(new PointerEvent('pointerup', { bubbles: true, pointerId: 1 }));
return document.querySelector('.time .pane-head .dim').textContent;
return document.querySelector('.time .pane-head .at-frame').textContent;
})()`;
// Everything the page has to say about loading, saving and opening. Read off the
@ -231,10 +231,15 @@ const STATUS = `[...document.querySelectorAll('.top .status, .pool .pane-body >
// pane each one lived in would be a second copy of the layout.
//
// `firstChild` is the label: a media-pool row has a second line in a child span,
// so matching on textContent would never find "take".
// so matching on textContent would never find "take". `aria-label` is the same
// label for a control whose face is a glyph — the transport's play and pause —
// and it is the right fallback rather than a test hook, because it is already
// what that button is called for anybody not reading it with their eyes.
const CLICK = (label) => `(() => {
const want = ${JSON.stringify(label)};
const b = [...document.querySelectorAll('button')]
.find((b) => (b.firstChild?.textContent ?? '').trim() === ${JSON.stringify(label)});
.find((b) => (b.firstChild?.textContent ?? '').trim() === want
|| b.getAttribute('aria-label') === want);
if (!b || b.disabled) return false;
b.click();
return true;
@ -626,7 +631,7 @@ async function main() {
check(irisSlider !== null, 'the stage eye has an iris-size slider');
if (irisSlider) {
check(await page.eval(CLICK('play')), 'the stage starts playing');
const startFrame = await page.eval(`Number(document.querySelector('.time .pane-head .dim').textContent.match(/\\d+/)[0])`);
const startFrame = await page.eval(`Number(document.querySelector('.time .pane-head .at-frame').textContent.match(/\\d+/)[0])`);
await page.send('Input.dispatchMouseEvent', {
type: 'mousePressed', x: irisSlider.x, y: irisSlider.y, button: 'left', clickCount: 1,
});
@ -638,7 +643,7 @@ async function main() {
check(preview !== null, 'the slider updates the stage preview', preview ?? debug);
check(debug.includes(':face-1/eye-r') && debug.includes('tier 1 only'),
'the panel reports the affected feature and tier', debug);
const endFrame = await page.eval(`Number(document.querySelector('.time .pane-head .dim').textContent.match(/\\d+/)[0])`);
const endFrame = await page.eval(`Number(document.querySelector('.time .pane-head .at-frame').textContent.match(/\\d+/)[0])`);
check(endFrame > startFrame, 'playback continues during tuning', `${startFrame} -> ${endFrame}`);
await page.eval(CLICK('pause'));
}