← Commit history

2.15.4: restore sendbar/send-panel/demo-floaty CSS; gate appearance

John Lauer ·0646131de8 ·1mo ago ·parent 4ab4e8d
5 files changed +103−3
Cargo.toml+1−1
@@ -1,6 +1,6 @@ [package] name = "adom-lbr"-version = "2.15.3"+version = "2.15.4" edition = "2021" description = "adom-lbr generator / EDA translator: the canonical adom-lbr JSON is the hub, with native converters to Altium (.SchLib/.PcbLib/.IntLib), EAGLE/Fusion (.lbr), and KiCad. Altium output is written natively — no Altium needed at conversion time." 
VERSION+1−1
@@ -1 +1 @@-2.15.3+2.15.4
package.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "adom-lbr",-  "version": "2.15.3",+  "version": "2.15.4",   "type": "app",   "description": "adom-lbr \u2014 the EDA library translator. Bring a component in from any supported EDA tool and convert it to any other (KiCad \u21c4 Altium \u21c4 EAGLE/Fusion) through one canonical adom-lbr JSON \u2014 symbol + footprint + 3D + pin\u2194pad map. Altium is written natively (no Altium needed). Includes the adom-lbr Manager: browse wiki components and view symbol/footprint/3D + the per-EDA layer stackup.",   "dependencies": {},
src/manage.html+72
@@ -71,6 +71,78 @@      The vertical padding is still mine, and so is anything the app body wants BELOW the      panel, which is where extra margin belongs if this page ever needs it. */   #content{padding:20px 16px 24px}+  /* ---- The send-evidence panel and the demo floaty ----+     ALSO RESTORED, and also destroyed by 2.14.0's regex. Both are features the user asked+     for by name: the progress bar, streaming console and evidence images that prove what+     was actually sent to KiCad or Fusion, and the play/pause/next/prev floaty that lets a+     newcomer stop the demo. Their markup and their JavaScript survived, so every gate I+     have passed: the elements exist, the handlers run, the module mounts. Only their+     appearance was gone, and appearance is the one thing none of my checks could see. */+  #sendpanel{position:fixed;right:14px;bottom:14px;z-index:1500;width:min(480px,92vw);background:var(--elevated);border:1px solid var(--border);border-left:3px solid var(--accent);border-radius:12px;box-shadow:0 16px 48px #000c;display:none}+  #sendpanel.show{display:block}+  #sendpanel .sp-head{display:flex;align-items:center;gap:10px;padding:10px 12px 8px 14px}+  #sendpanel .sp-head h3{margin:0;font:600 13.5px var(--brand-heading);color:var(--text);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}+  #sendpanel .sp-body{padding:0 14px 12px}+  .sp-bar{height:6px;border-radius:999px;background:var(--overlay);overflow:hidden;margin:2px 0 4px}+  .sp-bar i{display:block;height:100%;background:var(--accent);border-radius:999px;width:0%;transition:width .4s ease}+  .sp-bar.ind i{width:30%;animation:spslide 1.2s ease-in-out infinite alternate}+  @keyframes spslide{from{margin-left:0}to{margin-left:70%}}+  .sp-step{font:11.5px var(--brand-body);color:var(--text-2);margin-bottom:6px;min-height:15px}+  #sp-console{background:#0b0e13;border:1px solid var(--border);border-radius:8px;padding:8px 10px;font:11px/1.5 ui-monospace,monospace;color:#c9d1d9;max-height:150px;overflow:auto;white-space:pre-wrap;margin-bottom:8px}+  #sp-shots{display:flex;gap:8px;flex-wrap:wrap}+  #sp-shots figure{margin:0;width:104px}+  #sp-shots img{width:104px;height:70px;object-fit:cover;border:1px solid var(--border);border-radius:6px;background:#0d0f14;cursor:zoom-in;display:block}+  #sp-shots img:hover{border-color:var(--accent)}+  #sp-shots figcaption{font:10px var(--brand-body);color:var(--text-2);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}+  #sp-zoom{position:fixed;inset:0;z-index:4000;background:rgba(0,0,0,.75);display:none;align-items:center;justify-content:center;cursor:zoom-out}+  #sp-zoom img{max-width:92vw;max-height:92vh;border:1px solid var(--border);border-radius:8px}+  #tour-card{position:fixed;z-index:3001;width:min(400px,90vw);background:var(--elevated);border:1px solid var(--border);border-left:3px solid var(--accent);border-radius:12px;padding:14px 16px;box-shadow:0 16px 48px #000c;display:none}+  #tour-card h3{margin:0 0 6px;font:700 15px var(--brand-heading);color:var(--text);display:flex;align-items:center;gap:8px}+  #tour-card .step-n{font:600 10px var(--brand-body);color:var(--on-accent);background:var(--accent);border-radius:999px;padding:2px 8px}+  #tour-card p{margin:0 0 12px;font:13px/1.55 var(--brand-body);color:var(--text-body)}+  #tour-card p b{color:var(--text)}+  #tour-card .row{display:flex;gap:8px;align-items:center}+  #tour-card .row .spacer{flex:1;font:11px var(--brand-body);color:var(--text-2)}+  #tour-card button{background:#1a2130;border:1px solid var(--border);color:var(--ink);border-radius:7px;padding:6px 14px;font:600 12.5px var(--brand-heading);cursor:pointer}+  #tour-card button:hover{border-color:var(--accent)}+  #tour-card button.primary{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}+  #tour-card button:active{transform:translateY(1px)}+  #tour-bar{position:fixed;left:50%;bottom:18px;transform:translateX(-50%);z-index:3002;display:none;align-items:center;gap:6px;background:var(--elevated);border:1px solid var(--border);border-radius:999px;padding:6px 10px;box-shadow:0 12px 36px #000c}+  #tour-bar.show{display:flex}+  #tour-bar button{width:34px;height:34px;border-radius:50%;border:1px solid var(--border);background:#1a2130;color:var(--ink);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;transition:border-color .12s,background .12s,transform .06s}+  #tour-bar button:hover{border-color:var(--accent);color:var(--accent)}+  #tour-bar button:active{transform:translateY(1px)}+  #tour-bar button.play{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}+  #tour-bar .tn{font:600 11.5px var(--brand-body);color:var(--text-2);padding:0 6px;min-width:44px;text-align:center}+  /* ---- Send to KiCad / Send to Fusion ----+     RESTORED. These nineteen rules were deleted by the same over-greedy regex in 2.14.0 that+     took the api() helper. That edit is now known to have destroyed TWO things, and only one+     of them was ever found by a check: the missing function broke behaviour, so the gates+     caught it, while the missing stylesheet broke only APPEARANCE, so the page kept passing+     every structural, behavioural and conformance check for five releases while this bar+     rendered as bare labels and unstyled white buttons in the user's dock. It was found by+     LOOKING AT A SCREENSHOT of the real pane. A gate that asserts behaviour cannot see a+     stylesheet that is simply gone, exactly as a byte-check could not see a missing+     function. Both halves of that lesson cost a day. */+  #sendbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:8px 18px;background:var(--panel);border-bottom:1px solid var(--edge);font-size:12px}+  #sendbar .grp{display:flex;align-items:center;gap:6px}+  #sendbar .lab{color:var(--mut);font:600 11px var(--brand-heading);text-transform:uppercase;letter-spacing:.05em}+  #sendbar button{background:#1a2130;border:1px solid var(--edge);color:var(--ink);border-radius:7px;padding:5px 10px;font-size:12px;cursor:pointer;transition:border-color .12s,background .12s,transform .06s}+  #sendbar button:hover:not(:disabled){border-color:var(--acc);background:#12302f}+  #sendbar button:active:not(:disabled){transform:translateY(1px)}+  #sendbar button:disabled{opacity:.45;cursor:not-allowed}+  #sendbar .sep{width:1px;height:18px;background:var(--edge)}+  #sendbar .abdot{display:inline-flex;align-items:center;gap:6px;margin-left:auto;color:var(--mut)}+  #sendbar .abdot i{width:8px;height:8px;border-radius:50%;background:#555;display:inline-block}+  #sendbar .abdot.on i{background:var(--green);box-shadow:0 0 6px var(--green)}+  .splitgrp{position:relative;gap:0}+  .splitgrp>button:first-child{border-radius:7px 0 0 7px;border-right:none}+  .splitgrp .caret{border-radius:0 7px 7px 0;padding:5px 6px;display:inline-flex;align-items:center}+  .dropmenu{position:absolute;top:calc(100% + 6px);left:0;z-index:1200;min-width:180px;background:var(--elevated);border:1px solid var(--border);border-radius:9px;box-shadow:0 12px 32px #000a;padding:5px;display:flex;flex-direction:column;gap:2px}+  .dropmenu[hidden]{display:none}+  .dropmenu button{text-align:left;background:none;border:none;border-radius:6px;padding:7px 10px;color:var(--ink);font-size:12.5px;cursor:pointer}+  .dropmenu button:hover:not(:disabled){background:#12302f;color:var(--acc)}+  .dropmenu button:disabled{opacity:.45;cursor:not-allowed}   /* tooltips (tooltips skill): 600ms, body-appended, clamped */   #tip2{position:fixed;z-index:5000;background:var(--overlay);border:1px solid var(--line);color:var(--text);font:12px var(--brand-body);padding:5px 9px;border-radius:6px;pointer-events:none;display:none;max-width:280px}   /* sidebar mode tabs: Projects (boards) | Parts (the whole wiki library) */
tools/page-smoke.js+28
@@ -117,6 +117,34 @@ const EXPECT = {     console.log('[smoke] FAIL javascript errors on load (including ones the page swallows):');     [...new Set(real)].slice(0, 6).forEach(e => console.log('        ' + e.slice(0, 160)));   }+  // ---- APPEARANCE, not just behaviour ----------------------------------------------+  // The 2.14.0 regex destroyed TWO things. The missing function broke behaviour and was+  // caught. The missing STYLESHEET broke only appearance, so the Send-to-KiCad bar, the+  // send-evidence panel and the demo floaty rendered as bare labels and unstyled buttons+  // for five releases while every gate stayed green. jsdom has no layout engine but it DOES+  // resolve the cascade, so a signature declared property per component is checkable here.+  // An id-orphan scan was tried first and abandoned: most ids are styled through class or+  // descendant rules, so it flagged 70 false positives and would have been switched off.+  const LOOKS = [+    ['#sendbar',        'display',      'flex',     'the Send to KiCad / Fusion bar'],+    ['#sendbar button', 'borderRadius', /\d/,       'the send buttons'],+    ['#sendpanel',      'position',     'fixed',    'the send-evidence panel'],+    ['#tour-card',      'position',     'fixed',    'the demo narration card'],+    ['#tour-bar',       'borderRadius', '999px',    'the demo play/pause floaty'],+    ['#sp-console',     'fontFamily',   /mono/,     'the streaming console'],+  ];+  let looksBad = 0;+  for (const [sel, prop, want, what] of LOOKS) {+    const el = d.querySelector(sel);+    if (!el) { bad++; looksBad++; console.log(`[smoke] FAIL ${what} (${sel}) is not in the page at all`); continue; }+    const got = dom.window.getComputedStyle(el)[prop] || '';+    const ok = want instanceof RegExp ? want.test(got) : got === want;+    if (!ok) { bad++; looksBad++; console.log(`[smoke] FAIL ${what} is unstyled: ${sel} ${prop} = ${got || '(empty)'}`); }+  }+  // never print a pass line next to a failure: a summary that says ok while a check+  // above it says FAIL is how a broken gate gets read as a working one+  if (!looksBad) console.log('[smoke] ok   ' + LOOKS.length + ' components carry their styling');+   // GRADUATION IS NOT DISMISSAL. The panel folding on its own after enough launches must   // not be recorded as the user dismissing it, or the fold becomes permanent. The module   // reports who moved the panel (newbie-panel 2.1.0 onToggle(open, source)); this asserts