Commit 640685b4 authored by vertighel's avatar vertighel
Browse files

Fase 5 JS punto 7: toggle di elementi pre-esistenti invece di injection



- control.js: .tab-new-badge non piu' createElement+style.cssText, ma
  <span class="tab-new-badge d-none"> pre-esistente nei 2 bottoni tab
  (control.html), toggle via classList. Sizing spostato in style.css
  (nuova sezione "9. Viewer tab new-frame badge").
- sequencer.js: l'alert "no steps" non piu' innerHTML ad ogni render,
  ma #no-steps-placeholder pre-esistente in sequencer.html, toggle
  via classList.
- NoctuaWidget.js: il bottone refresh non piu' style.display (in JS e
  nei 5 blueprint), ora .d-none su entrambi i lati.
- fits-viewer.js: cursore di pan non piu' style.cursor inline, una
  classe .noctua-cursor-grabbing per l'override; crosshair (stato di
  riposo) e' ora il default CSS di .cv-main in viewer.css.
- Fix collegato: viewer.css aveva .cv-principale che non combaciava
  con nulla (la classe reale e' .cv-main, drift italiano/inglese) --
  rinominato. .cv-teccam invece resta segnalato ma non toccato: non
  esiste in nessuna pagina/JS, non e' un typo di rename come
  .cv-principale, serve una decisione separata (assegnare la classe
  al canvas teccam o cancellare la regola morta).
- Verificato con node --check e parsing Jinja sui file toccati.
- PLAN.md aggiornato.

Co-Authored-By: default avatarClaude Sonnet 5 <noreply@anthropic.com>
parent 8f158fcd
Loading
Loading
Loading
Loading
+55 −4
Original line number Diff line number Diff line
@@ -543,13 +543,64 @@ Working point by point per the user's request, checking in after each
      `console.error`d, no `showToast` — added the `.ok` check +
      `extractErrorMessage` + `showToast` on failure to both, matching
      every sibling handler now.
- [ ] `NoctuaWidget.js`: switch its 2 ad-hoc error-alert strings to
      `showToast()`.
- [ ] Convert the confirmed injected-HTML/CSS candidates to
- [x] `NoctuaWidget.js`: switch its 2 ad-hoc error-alert strings to
      `showToast()`. Both `this.innerHTML = '<div class="alert
      alert-danger...">...'` replaced with `showToast(..., 'danger')`
      + `import { showToast } from '../ui.js'`. The widget's own slot
      is left empty on failure now (no inline alert div rendered
      in-place) rather than showing broken content — matches how
      every other module surfaces errors, confirmed `ui.js` is
      already loaded as a module on `snippet_viewer.html` (the only
      page using this component, via `base.html`). Verified with
      `node --check`.
- [x] Convert the confirmed injected-HTML/CSS candidates to
      toggle-a-pre-existing-element (see `dev/conventions/
      javascript.md` for the exact list — most createElement/innerHTML/
      inline-style call sites are genuinely dynamic and should stay as
      they are, only a handful are real candidates).
      they are, only a handful are real candidates). All 5 done:
      - `control.js`'s `.tab-new-badge` dot: was created/removed with
        `createElement`+inline `style.cssText`. Now a pre-existing
        `<span class="tab-new-badge d-none ...">` inside each of the 2
        tab buttons in `control.html`, toggled via `classList`; sizing
        moved from inline `cssText` to a new `.tab-new-badge` rule in
        `style.css` (new "9. Viewer tab new-frame badge" section).
      - `sequencer.js`'s "no steps" alert: was a static string
        re-injected via `innerHTML` on every `renderEditor()` call.
        Now a pre-existing `#no-steps-placeholder` sibling of
        `#editor-form-container` in `sequencer.html`, toggled via
        `classList`.
      - `NoctuaWidget.js`'s refresh-button visibility: was
        `refreshBtn.style.display = 'inline-block'` fighting an inline
        `style="display: none;"` in all 5 blueprint templates
        (`widget_blueprints.html`). Both sides now use `.d-none`
        (added to the button's class list in the templates, toggled
        via `classList.remove('d-none')` in JS).
      - `fits-viewer.js`'s pan cursor (marked "minor, not urgent" in
        the doc, done anyway for completeness): `cvMain.style.cursor =
        'grabbing'/'crosshair'` on mousedown/mouseup replaced with one
        `.noctua-cursor-grabbing` class toggled during the pan;
        `crosshair` (the resting state) is now the `.cv-main` element's
        own CSS default in `viewer.css`, so only the override needs a
        class at all.
      - Found in passing and fixed on the user's go-ahead (initially
        flagged as out of scope, then folded in): `viewer.css`'s
        `.cv-principale` selector didn't match anything — the real
        HTML/JS class is `.cv-main` (`macros/viewer_panel.html:29`,
        `fits-viewer.js:98`), an Italian/English naming drift.
        Renamed both occurrences to `.cv-main`, so it now actually
        gets `user-select:none`/`-webkit-user-drag:none`/`pixelated`
        image-rendering. **Not** fixed, still dead, flagged only:
        `.cv-teccam` (same file) doesn't match anything either —
        grepped every page/macro/JS file, no `cv-teccam` class exists
        anywhere, so unlike `.cv-principale` this isn't a rename typo,
        it looks like the teccam canvas either never got this class or
        was renamed away with the rule left behind. Left alone since
        the user asked specifically about the `.cv-main` mismatch, not
        this one — separate decision needed on whether the teccam
        canvas should get the class or the dead rule should just be
        deleted.
      Verified with `node --check` on all touched JS and a Jinja parse
      check on all touched HTML.
- [ ] Remove dead code: `noctuaUpdateFromRest` + its window shim,
      unused `ui-core.js` exports (`formatValue`, `noctuaMaps`,
      confirm `getStatusType`).
+2 −2
Original line number Diff line number Diff line
@@ -265,8 +265,8 @@
      
      <div class="card-header p-0 border-secondary d-flex align-items-center">
        <ul class="nav nav-tabs border-0 flex-grow-1" role="tablist">
          <li class="nav-item"><button class="nav-link active py-2" data-bs-toggle="tab" data-bs-target="#mon-fits">Scicam</button></li>
          <li class="nav-item"><button class="nav-link py-2" data-bs-toggle="tab" data-bs-target="#mon-teccam">Teccam</button></li>
          <li class="nav-item"><button class="nav-link active py-2" data-bs-toggle="tab" data-bs-target="#mon-fits">Scicam<span class="tab-new-badge d-none badge rounded-pill bg-warning ms-1 p-0"></span></button></li>
          <li class="nav-item"><button class="nav-link py-2" data-bs-toggle="tab" data-bs-target="#mon-teccam">Teccam<span class="tab-new-badge d-none badge rounded-pill bg-warning ms-1 p-0"></span></button></li>
          <li class="nav-item"><button class="nav-link py-2" data-bs-toggle="tab" data-bs-target="#mon-webcam">Webcam</button></li>
          <li class="nav-item"><button class="nav-link py-2" data-bs-toggle="tab" data-bs-target="#mon-synoptic">Synoptic</button></li>
          <li class="nav-item"><button class="nav-link py-2" data-bs-toggle="tab" data-bs-target="#mon-output">Output</button></li>
+10 −15
Original line number Diff line number Diff line
@@ -7,11 +7,10 @@
      <span class="widget-title text-light fw-semibold text-capitalize">Device</span>
      <div class="status-container d-flex align-items-center gap-1">
        <span class="badge bg-secondary font-monospace widget-status-badge" data-status="">N/A</span>
        <button class="btn btn-sm btn-outline-secondary py-0 px-1 btn-refresh btn-control" 
        <button class="btn btn-sm btn-outline-secondary py-0 px-1 btn-refresh btn-control d-none" 
                title="Refresh state" 
                data-control="" 
                data-method="GET" 
                style="display: none;"></button>
                data-method="GET"></button>
      </div>
    </div>        
  </div>
@@ -24,11 +23,10 @@
      <span class="widget-title text-light fw-semibold text-capitalize">Boolean Control</span>
      <div class="status-container d-flex align-items-center gap-1">
        <span class="badge bg-secondary font-monospace widget-status-badge" data-status="">N/A</span>
        <button class="btn btn-sm btn-outline-secondary py-0 px-1 btn-refresh btn-control" 
        <button class="btn btn-sm btn-outline-secondary py-0 px-1 btn-refresh btn-control d-none" 
                title="Refresh state" 
                data-control="" 
                data-method="GET" 
                style="display: none;"></button>
                data-method="GET"></button>
      </div>
    </div>
    <div class="btn-group btn-group-sm w-100">
@@ -45,11 +43,10 @@
      <span class="widget-title text-light fw-semibold text-capitalize">Dual Input</span>
      <div class="status-container d-flex align-items-center gap-1">
        <span class="badge bg-secondary font-monospace widget-status-badge" data-status="">N/A</span>
        <button class="btn btn-sm btn-outline-secondary py-0 px-1 btn-refresh btn-control" 
        <button class="btn btn-sm btn-outline-secondary py-0 px-1 btn-refresh btn-control d-none" 
                title="Refresh state" 
                data-control="" 
                data-method="GET" 
                style="display: none;"></button>
                data-method="GET"></button>
      </div>
    </div>
    <div class="input-group input-group-sm">
@@ -73,11 +70,10 @@
      <span class="widget-title text-light fw-semibold text-capitalize">Action</span>
      <div class="status-container d-flex align-items-center gap-1">
        <span class="badge bg-secondary font-monospace widget-status-badge" data-status="">N/A</span>
        <button class="btn btn-sm btn-outline-secondary py-0 px-1 btn-refresh btn-control" 
        <button class="btn btn-sm btn-outline-secondary py-0 px-1 btn-refresh btn-control d-none" 
                title="Refresh state" 
                data-control="" 
                data-method="GET" 
                style="display: none;"></button>
                data-method="GET"></button>
      </div>
    </div>
    <button class="btn btn-sm btn-outline-danger w-100 btn-control" data-control="" data-method=""></button>
@@ -91,11 +87,10 @@
      <span class="widget-title text-light fw-semibold text-capitalize">Single Input</span>
      <div class="status-container d-flex align-items-center gap-1">
        <span class="badge bg-secondary font-monospace widget-status-badge" data-status="">N/A</span>
        <button class="btn btn-sm btn-outline-secondary py-0 px-1 btn-refresh btn-control" 
        <button class="btn btn-sm btn-outline-secondary py-0 px-1 btn-refresh btn-control d-none" 
                title="Refresh state" 
                data-control="" 
                data-method="GET" 
                style="display: none;"></button>
                data-method="GET"></button>
      </div>
    </div>
    <div class="input-group input-group-sm">
+1 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
                <div id="editor-form-container">
                    <div class="alert alert-secondary text-center py-5">Select an OB to start.</div>
                </div>
                <div id="no-steps-placeholder" class="alert alert-secondary text-center py-5 d-none">No steps in this OB. Use + APPEND to add one.</div>
                <textarea id="editor-raw" class="form-control bg-black text-light font-monospace d-none" style="height: 500px;"></textarea>
            </div>
            
+11 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
 * 6. Subsystem guard
 * 7. Disabled field styling
 * 8. Mode selector tabs
 * 9. Viewer tab new-frame badge
 */


@@ -160,3 +161,13 @@ label:has(~ div :disabled) {
    background-color: var(--bs-info);
    border-color: var(--bs-info);
}


/* ── 9. Viewer tab new-frame badge ─────────────────────────────────────── */

.tab-new-badge {
    width: 7px;
    height: 7px;
    display: inline-block;
    vertical-align: middle;
}
Loading