From 2ec6fc8cdb34968f752d018e3a41285d35cf66d2 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Sat, 18 Jul 2026 17:21:24 -0500 Subject: feat(gallery): bring the needle-through-edge ten to the extraction bar crossNeedle, thermometer, bourdon, stripChart, corrMeter, battCells, mcVu, chromeMinMax, aviationGauge, and edgeMeter each get the contract comment. The six DOM builders take dupre- prefixes across their markup and CSS blocks. Internals go compound where gauge, fader, and nixie already hold the plain names: bourdon's needle, hub, and cap, corrMeter's face, arc, needle, and label, crossNeedle's arc, and thermometer's tube and fill. crossNeedle's nA and nB become dupre-fwd and dupre-rfl, and battCells moves its cell modifiers to the shared dupre-on and dupre-warn. The handles now enforce their documented domains: the needle meters clamp set() to 0-100, stripChart floors its history at two samples and survives a non-array set(), battCells floors its cell count at one, and mcVu clamps and paints opts.value at build instead of ignoring it for a hard-coded .35. Two probe checks cover the gates and drive the renamed DOM. Extraction audit: 84/111 contract comments. --- tests/gallery-probes/probe.mjs | 62 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'tests/gallery-probes') diff --git a/tests/gallery-probes/probe.mjs b/tests/gallery-probes/probe.mjs index 02b1062..0539da0 100644 --- a/tests/gallery-probes/probe.mjs +++ b/tests/gallery-probes/probe.mjs @@ -1340,6 +1340,68 @@ try { ok('voiceLoop cycles through prefixed DOM: demo default, exclusive talk, own set idle', b7dom === JSON.stringify({ nKeys: 8, mon0: 3, tlk0: 1, mon1: 4, tlk1: 1, fdTalks: true, fdIdle: true, ownIdle: true }), b7dom); + // batch-8 domain gates on detached hosts: the needle meters clamp set() to + // their documented 0-100, stripChart floors its history at two samples and + // survives a non-array set(), battCells floors its cell count at one. + const clamps8 = await evl(`(() => { + const xn = DUPRE.crossNeedle(document.createElement('div')); + xn.set(150); const xnHi = xn.get(); xn.set(-10); const xnLo = xn.get(); + const th = DUPRE.thermometer(document.createElement('div')); + th.set(-5); const thLo = th.get(); + const bd = DUPRE.bourdon(document.createElement('div')); + bd.set(200); const bdHi = bd.get(); + const st = DUPRE.stripChart(document.createElement('div'), { samples: 1 }); + st.set(null, 0.5); + const stPts = st.el.querySelector('polyline').getAttribute('points'); + let cmTxt; const cm = DUPRE.corrMeter(document.createElement('div'), { onChange: (v, t) => cmTxt = t }); + cm.set(200); const cmHi = cm.get(); + const bc = DUPRE.battCells(document.createElement('div'), { cells: -3 }); + const bcCells = bc.el.querySelectorAll('.dupre-cell').length; + bc.set(-10); const bcLo = bc.get(); + const vu = DUPRE.mcVu(document.createElement('div'), { value: 5 }); + const vuInit = vu.get(); + const vuNdl = vu.el.querySelector('line[stroke-width="1.6"]').getAttribute('transform'); + return JSON.stringify({ xnHi, xnLo, thLo, bdHi, stOk: !stPts.includes('NaN'), cmHi, cmTxt, bcCells, bcLo, vuInit, vuNdl }); + })()`); + ok('batch-8 domain gates: needle-meter clamps, stripChart array/floor guards, battCells cell floor, mcVu init', + clamps8 === JSON.stringify({ xnHi: 100, xnLo: 0, thLo: 0, bdHi: 100, stOk: true, + cmHi: 100, cmTxt: '+1.00', bcCells: 1, bcLo: 0, vuInit: 1.02, vuNdl: 'rotate(43,75,112)' }), clamps8); + + // batch-8 state through the prefixed DOM (catches rename stragglers): the + // battery lights dupre-on cells and tints dupre-warn under the threshold, + // the crossed needles and mercury column track set() through their renamed + // internals. + const b8dom = await evl(`(() => { + const bc = DUPRE.battCells(document.createElement('div')); + const nCells = bc.el.querySelectorAll('.dupre-cell').length; + const on62 = bc.el.querySelectorAll('.dupre-cell.dupre-on').length; + const warn62 = bc.el.querySelectorAll('.dupre-warn').length; + bc.set(20); + const on20 = bc.el.querySelectorAll('.dupre-cell.dupre-on').length; + const warn20 = bc.el.querySelectorAll('.dupre-cell.dupre-warn.dupre-on').length; + const xn = DUPRE.crossNeedle(document.createElement('div')); + xn.set(0); + const fwdT = xn.el.querySelector('.dupre-fwd').style.transform; + const rflT = xn.el.querySelector('.dupre-rfl').style.transform; + const th = DUPRE.thermometer(document.createElement('div')); + th.set(75); + const thH = th.el.querySelector('.dupre-thermo-fill').style.height; + const bd = DUPRE.bourdon(document.createElement('div')); + bd.set(50); + const bdT = bd.el.querySelector('.dupre-bourdon-ndl').style.transform; + const cm = DUPRE.corrMeter(document.createElement('div')); + cm.set(50); + const cmT = cm.el.querySelector('.dupre-corr-ndl').style.transform; + const stc = DUPRE.stripChart(document.createElement('div')); + stc.push(1); + const penT = stc.el.querySelector('.dupre-pen').style.top; + return JSON.stringify({ nCells, on62, warn62, on20, warn20, fwdT, rflT, thH, bdT, cmT, penT }); + })()`); + ok('batch-8 renamed DOM tracks state: battery on/warn cells, needles and pen move', + b8dom === JSON.stringify({ nCells: 8, on62: 5, warn62: 0, on20: 2, warn20: 2, + fwdT: 'rotate(-42deg)', rflT: 'rotate(42deg)', thH: '75%', bdT: 'rotate(0deg)', + cmT: 'rotate(0deg)', penT: '3px' }), b8dom); + // late exceptions from interactions const errs2 = events.filter(e => e.method === 'Runtime.exceptionThrown'); ok('no exceptions after interaction', errs2.length === 0); -- cgit v1.2.3