Every one of these was silent at the code level and loud in a real
browser; each fix carries its own tripwire (render pin, unit pin, or
CSP-safe rewrite) so the class cannot quietly return.
1. Theme picker dead since the CSP migration (eb57b720): the Appearance
panel's theme buttons emitted `@click="selectTheme(opt.Name)"` as
LITERAL text (templ gotcha #1 — quoted attribute values are never
interpolated; `opt` is a Go loop var), so Alpine threw "Undefined
variable: opt" on every click and no PUT /api/auth/theme ever fired.
The wood-paneling sibling always used the correct expression form,
which is why the panel half-worked. Fixed to the interpolated form;
TestThemePickerHandlersAreInterpolated pins that real theme names
reach the HTML and the raw identifier never does.
2. Filter-builder op dropdown "does nothing": the field ingest
hardcoded `ops: []` into every field's meta while only mirroring the
ops into the global label registry — opsFor() returned [] for EVERY
field, so the op menu rendered zero items: an invisible menu, no
console error (user tried author/publisher/title/subtitle, all
equally dead). FieldMeta.ops is now the wire's op objects, opsFor()
is a standalone exported helper, and opsForField unit tests pin the
round-trip. Verified live: the field menu opens/closes while the op
menu stayed shut, both with identical wiring — the difference was
the data, not the wiring.
3. AND/OR connective chip dead: the chip carried an `if` STATEMENT in
the Alpine attribute (`@click="if (row.chipClickable) ..."`) which
the CSP build's evaluator rejects as a statement — the whole
expression silently never ran. Moved the clickability check into a
toggleConnective(row) component method; the attribute is now a plain
method call.
4. Pencil vs card navigation race: navigateToCollection guarded with
`event.target instanceof HTMLElement`, which is FALSE for the
pencil glyph's SVGElement — a click landing on the glyph sailed past
the guard and navigated while the htmx edit-modal request still
fired (the reported "modal flashes, then the builder page"). The
guard now uses target.closest("button") (works on SVGElement) and
takes $event explicitly instead of the deprecated window.event.
.icon-btn is already a 36px square, so no hit-area change needed.
5. Add Items modal under the sidebar + taller than the window: the
picker overlay sat at z-50 UNDER the app-sidebar's z-60 (its left
edge rendered beneath the nav), and the card had no height bound —
header + tabs + filters + grid + footer overflow short windows with
the footer unreachable (fixed overlay, no page scroll). The picker
and create-modal overlays move to z-[65], both confirm dialogs to
z-[70], and the picker card is now a flex column capped at
max-h-[85vh] whose grids flex-fill (they grow on tall windows,
shrink on short ones). The ladder is documented at .app-sidebar in
input.css: sidebar 60 / overlays 65 / confirm 70 / toasts 9999.
Found by clicking every control the way a user does (panel clicks +
computed-style reads + screenshots) after the previous sweep trusted
DOM-text snapshots, which show hidden menus' text and cannot see
occlusion, stacking, or geometry at all.
91 lines
1.3 KiB
Plaintext
91 lines
1.3 KiB
Plaintext
# Build artifacts
|
|
bookhoard
|
|
bookhoard.*
|
|
/server
|
|
|
|
# Node.js
|
|
node_modules/
|
|
npm-debug.log*
|
|
yarn-debug.log*
|
|
yarn-error.log*
|
|
package-lock.json
|
|
.pnpm-debug.log*
|
|
|
|
# TypeScript
|
|
*.tsbuildinfo
|
|
*.d.ts.map
|
|
*.map
|
|
|
|
# Compiled JavaScript (keep .ts source, ignore .js)
|
|
# Exception: Downloaded documentation dependencies
|
|
web/static/compiled-*.js
|
|
web/static/*.js
|
|
web/static/*.mjs
|
|
web/static/assets/*.js
|
|
web/static/text_layer_builder*.css
|
|
web/static/annotation_layer_builder*.css
|
|
|
|
# Downloaded documentation dependencies (tracked in git)
|
|
!web/static/htmx.min.js
|
|
!web/static/highlight.min.js
|
|
!web/static/highlight-dark.min.css
|
|
!web/static/lunr.min.js
|
|
!web/static/lunr-flex.min.js
|
|
|
|
# Temporary files
|
|
tmp/
|
|
temp/
|
|
*.tmp
|
|
*.swp
|
|
*.swo
|
|
*~
|
|
|
|
# Testing coverage
|
|
*.out
|
|
*.cover
|
|
coverage.html
|
|
*.test
|
|
|
|
# Logs
|
|
*.log
|
|
*.log.*
|
|
|
|
# Environment
|
|
.env
|
|
!.env.example
|
|
.env.test
|
|
.env.local
|
|
|
|
# IDE
|
|
.idea/
|
|
.zed/
|
|
.vscode/
|
|
.opencode/
|
|
*.iml
|
|
.DS_Store
|
|
Thumbs.db
|
|
|
|
# Uploads
|
|
uploads/
|
|
|
|
# Vendored build artifacts (copied from node_modules at build time)
|
|
web/static/vendor/
|
|
|
|
# Database
|
|
*.db
|
|
*.sqlite
|
|
*.sqlite3
|
|
|
|
VALID_TOKEN
|
|
fresh_token.txt
|
|
session-*.md
|
|
|
|
# Local prod-export scratch: personal annotation/reading data, never commit
|
|
/export/
|
|
|
|
# Binary media fixtures: never commit (generate with ffmpeg at test time,
|
|
# see docs/contributing/development.md → Media fixtures)
|
|
internal/services/testdata/
|
|
test-results
|
|
.openchamber/
|