Changeset 1e172f3 in Klonkt for src/views/partials/bottom-tab.ejs


Ignore:
Timestamp:
08/07/2026 12:00:22 PM (5 weeks ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
4c1e327
Parents:
ea138c0
git-author:
Robin <roboburr@…> (08/07/2026 12:00:20 PM)
git-committer:
roboburr <roboburr@…> (08/07/2026 12:00:22 PM)
Message:

Modules laden vanuit de shell in plaats van inline script (shaer-bqr, stap 1)

Het mechanisme uit optie C, met de bottom-tab als eerste geval zodat het ook
te bewijzen is.

WAAROM. De CSP-nonce rouleert per verzoek (shaer-0i6). Een script dat via htmx
binnenkomt draagt dus een nonce die het document niet kent en wordt geweigerd.
De chrome komt bij ELKE navigatie out-of-band opnieuw binnen, dus daar valt de
JS bij de eerste klik binnen de site al weg.

HOE. Een bootstrap in shell.ejs -- die komt alleen bij een volledige laadbeurt
binnen en heeft dus wel de goede nonce. Hij leest body[data-js], een lijst
modulenamen, en importeert ze uit /assets/js/mod/. Een dynamische import vanuit
een vertrouwd script is precies waar strict-dynamic voor bedoeld is, dus de
module zelf heeft geen nonce nodig.

Bij een htmx-navigatie zet de pcmsNav-trigger data-js opnieuw en haalt de
bootstrap op wat er nieuw bij staat. 'chrome' staat er altijd bij.

De naam wordt een PAD, dus hij moet door /[a-z0-9-]+$/ -- geen punt, geen
schuine streep.

EERSTE GEVAL: de zoekknop van de bottom-tab. Geen servergegevens erin, al
gedelegeerd, al voorzien van een slot -- dus de verhuizing verandert niets aan de
logica en het mechanisme is er echt mee te toetsen.

WAT DIT BLOOTLEGT VOOR DE VOLGENDE STAP: het topnav-script interpoleert
vertalingen (<%= t('search.section_posts') %>) en kan dus niet zomaar een
statisch bestand worden. Servergegevens horen via een data-attribuut naar een
module, niet via interpolatie in de code. Dat is een eigen stap en staat als
zodanig in mod/chrome.js opgeschreven.

Templates compileren, suite 551/551. Het echte bewijs is een klik BINNEN de site:
na een herlading werkt alles toch al.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/views/partials/bottom-tab.ejs

    rea138c0 r1e172f3  
    302302</style>
    303303
    304 <script>
    305 // Bottom-tab search button → opens #search-overlay. Using event delegation + looking
    306 // up the overlay on EVERY click: the overlay lives in the chrome that is OOB-replaced
    307 // during htmx navigation, so a once-captured reference goes stale
    308 // (button did nothing afterwards). Guard against double-wiring.
    309 (function() {
    310   if (window.__btSearchWired) return;
    311   window.__btSearchWired = true;
    312   document.addEventListener('click', function(e) {
    313     if (!e.target.closest || !e.target.closest('#bottom-tab-search-toggle')) return;
    314     var o = document.getElementById('search-overlay');
    315     if (o) { o.hidden = false; var i = o.querySelector('input'); if (i) i.focus(); }
    316   });
    317 })();
    318 </script>
     304<%# De zoekknop zit nu in de chrome-module (assets/js/mod/chrome.js).
     305    Inline script hier wordt door de CSP geweigerd zodra deze partial via htmx
     306    binnenkomt, en dat is bij elke navigatie -- zie shaer-0i6. %>
Note: See TracChangeset for help on using the changeset viewer.